Десериализация буфера протокола и динамически загружаемая DLL

Я использую protobuf-net для буферизации моего протокола. У меня есть dll, которую я загружаю динамически. Я могу создать экземпляр класса данных, содержащегося в dll, и я могу использовать и изменять созданный объект данных. Однако, когда я пытаюсь сериализовать/десериализовать объект данных, я получаю следующий сбой:

{"Невозможно определить известный тип для ProtoIncludeAttribute: MyDataDLL.MyDataClass, MyDataDLL, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"}

а иногда и сбой, говорящий, что MyDataClass не является подклассом MyBaseClass, или что-то в этом роде. MyDataClass определенно наследуется от MyBaseClass, а MyBaseClass имеет тег ProtoInclude для MyDataClass.

Assembly theAssembly = Assembly.LoadFrom("MyDataDLL.dll");

Type theType = theAssembly.GetType("MyDataDLL.MyDataClass");

object theData = Activator.CreateInstance(theType);

using (FileStream theStream = File.Open(fileName, FileMode.OpenOrCreate))
{
    MethodInfo method = typeof(ProtoBuf.Serializer).GetMethod("Deserialize").MakeGenericMethod(theType);
    theData = method.Invoke(null, new object[] { theStream });                      
}

Сбой происходит на "method.invoke"

Если я ссылаюсь на dll в проекте и использую ее таким образом, я не получаю сбоя. Так что я знаю, что это рабочая dll.


Обновление: Да, MyDataClass и MyBaseClass находятся в одной сборке.

Вот список того, что мой код делает иначе, чем ваш тестовый класс, хотя он, вероятно, не является обширным: MyDataClass — 4-й в списке из 7 ProtoIncludes.

MyBaseClass содержит все поля данных, MyDataClass содержит логику функций, управляющих этими полями данных. Таким образом, в MyDataClass нет вызовов ProtoMember.

MyBaseClass реализует интерфейс IExtensible и имеет следующую функцию для обработки дополнительных данных:

private ProtoBuf.IExtension extensionObject;
ProtoBuf.IExtension ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)            {
    return ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing);
}

Вероятно, это ни на что не влияет, но мои ProtoContracts используют параметр Name.


person Dan Vogel    schedule 24.02.2009    source источник
comment
Re Любые дополнительные мысли?; Я не видел ваше редактирование, пока вы не добавили комментарий; Я могу изменить тест, чтобы отразить обновление (когда я получу секунду), но я не уверен, что IExtensible и т. д. повлияет на это.   -  person Marc Gravell    schedule 26.02.2009
comment
Я знаю, что это было давно, но теперь мне удалось воспроизвести это. Дайте мне знать, если вы все еще заинтересованы в исправлении...   -  person Marc Gravell    schedule 05.06.2009
comment
Да, определенно хочу знать, как это исправить. Первоначальная задача была как бы отложена, но из общего интереса я хотел бы знать, в чем проблема. Кроме того, мне, возможно, придется закончить его.   -  person Dan Vogel    schedule 05.06.2009
comment
Блин - я не заметил твой ответ (лучше бы он был комментарием к моему посту!). Это связано с контекстом загрузки, то есть с тем, как вы загружаете dll. Я поместил один уровень исправления в двоичный файл (доступный некоторое время назад) - или для полной поддержки способ сделать это - перехватить событие AppDomain.AssemblyResolve. Дайте мне знать, если вы хотите получить более подробную информацию. (но ответьте на мой пост, чтобы я это увидел!)   -  person Marc Gravell    schedule 17.07.2009


Ответы (1)


Хорошо, я буду исследовать. Я зарегистрировал это здесь. Должно быть весело ;-p Ради интереса, MyDataClass и MyBaseClass в одной сборке?

Кстати; в следующем выпуске я намерен включить Serialize и т. д., которые принимают Type (а не дженерики) — это сделает стек RPC «в процессе» намного проще, а также поможет вам в использовании.


Обновлять; Я добавил модульный тест и (в отдельной dll, загруженной через Assembly.LoadFrom тестовые классы). Юнит-тест пройден. Пожалуйста, не могли бы вы уточнить, что ваш код делает по-другому (мне нужно что-то, что я могу воспроизвести, чтобы исправить это).

person Marc Gravell    schedule 24.02.2009