2016-11-17 6 views
1

Я выбрал код, который возвращает объект типа, переданного в, где уведомление об изменении свойства обернуто в виртуальные свойства, с отслеживанием изменений для клиента. Этот новый тип будет совместно использоваться клиентом и сервером (сериализован с использованием protobuf.net). Я ограничен не использованием сторонних библиотек, кроме использования protobuf.net.Идентификатор базового класса IL Emit совпадает с наследуемым классом; protobuffer не принимает циклическое наследование

Проблема, с которой я сталкиваюсь, заключается в том, что при попытке сериализации списка новых объектов (например, TypeA) с использованием protobuffer я запускаю «Неожиданный подтип: TypeA», и когда я пытаюсь добавить SubType в качестве модели для протобуфера с использованием RuntimeTypeModel, я запускаю «Циклическое наследование не допускается», который protobuffer не принимает в это время, AFAIK.

Я новичок в Reflection.Emit - есть способ набрать новый класс, отличный от типа, который я испускаю, по крайней мере, по имени? В этом случае я могу преодолеть ограничение циклического наследования. Я бы хотел избежать создания/копирования новых объектов.

Например, выделяют новый объект, как:

NewTypeA 
-base TypeA 

вместо:

TypeA 
-base TypeA 
-sub-type TypeA 

IL Излучатель:

usage: Type aType = CreateProxy(TypeA); 
     Activator.CreateInstance(aType); 

public static Type CreateProxy(Type type) 
{ 
    var assmName = new AssemblyName("DynamicProxyAssembly"); 
    ab = AppDomain.CurrentDomain.DefineDynamicAssembly(assmName, AssemblyBuilderAccess.Run); 
    mb = _ab.DefineDynamicModule(assmName.Name); 

    TypeBuilder typeBuilder = mb.DefineType(type.Namespace + "." + type.Name + "__proxy", TypeAttributes.Public, type); 
    typeBuilder.AddInterfaceImplementation(typeof(INotifyPropertyChanged)); 

    FieldBuilder eventField = CreatePropertyChangedEvent(typeBuilder); 

    MethodBuilder raisePropertyChanged = CreateRaisePropertyChanged(typeBuilder, eventField); 

    MethodInfo isModifiedSetMethod = type.GetProperty("Modified").SetMethod; 

    foreach property in type where virtual, wrap method with propertychangednotification... 

    Type ret = typeBuilder.CreateType(); // this returns TypeA__proxy derived from itself (base=TypeA__proxy). 
} 
+1

Некоторый код поможет значительно. Совершенно непонятно, что вы имеете в виду «излучающий, отличный от типа, который вы излучаете». Производные классы всегда можно отбрасывать обратно в базовые классы, если это то, что вы имеете в виду. –

+0

@JeroenMostert большое спасибо, что посмотрели. Я прикрепил образец кода - пожалуйста, дайте мне знать, если вы хотите получить более подробную информацию о том, где я поставил псевдокод, чтобы обернуть виртуальные свойства с помощью свойства и изменения. – Option

+0

@JeroenMostert Я выбрал новый тип целиком и получаю те же ошибки от Protobuffer. Похоже, это то, как сериализация списка выполняется в protobuffer, и мне нужно посмотреть, как сериализуется список. Еще раз спасибо, что посмотрели. Я отправлю ответ, когда смогу. – Option

ответ

2

Оказывается, это был RuntimeTypeModel используется при сериализации через протобуфер. Не было ничего плохого в подклассификации испускаемого типа с производным типом.

мне нужно, чтобы добавить тип экземпляра вместо TypeA:

RuntimeTypeModel.Default.Add(typeof(TypeA), true).AddSubType(555, typeAinstance.GetType()); 

... прежде чем я:

RuntimeTypeModel.Default.Add(typeof(TypeA), true).AddSubType(555, TypeA); 

, который, конечно же, вернулся циклическую ошибку.

Я надеюсь, что это поможет кому-то в будущем.

Смежные вопросы