Десериализация буфера протокола и динамически загружаемая DLL - PullRequest
2 голосов
/ 24 февраля 2009

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

{"Невозможно определить известный тип для ProtoIncludeAttribute: MyDataDLL.MyDataClass, MyDataDLL, Version = 0.0.0.0, Culture = нейтральный, 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 является четвертым в списке из 7 ProtoInclude.

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.

1 Ответ

1 голос
/ 24 февраля 2009

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

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


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

...