2016-11-17 11 views
1

전달 된 유형의 객체를 반환하는 코드가 생성되었습니다. 여기서 propertychange 알림은 클라이언트에 대한 수정 추적과 함께 가상 속성으로 래핑됩니다. 이 새로운 유형은 클라이언트와 서버간에 공유됩니다 (protobuf.net을 사용하여 일련 화됨). protobuf.net을 사용하는 것 이외에 타사 라이브러리를 사용하지 않는 것으로 제한됩니다.IL Emit 기본 클래스 이름은 상속 된 클래스와 동일합니다. protobuffer가 순환 상속을 허용하지 않습니다.

내가 겪고있는 문제는 protobuffer를 사용하여 새로운 개체 (예 : TypeA) 목록을 직렬화하려고하면 "예기치 않은 하위 유형 : TypeA"로 실행되고 SubType을 RuntimeTypeModel을 사용하는 protobuffer의 모델로 사용하면 "원형 상속을 사용할 수 없습니다"라는 오류 메시지가 나타납니다.이 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 정말 고맙습니다. 코드의 샘플을 첨부했습니다. 가상의 속성을 propertychanged로 바꾸고 수정하기 위해 가상 코드를 제공 한 세부 정보를 원한다면 알려주십시오. – Option

+0

@ JeroenMostert 새로운 유형을 완전히 방출했으며 Protobuffer에서 같은 오류가 발생합니다. protobuffer에서 목록 직렬화가 수행되는 방법 인 것처럼 보입니다. 목록이 serialize되는 방식을 살펴볼 필요가 있습니다. 다시 한번 검토해 주셔서 감사합니다. 내가 할 수 있으면 대답을 게시 할 것이다. – Option

답변

2

는 직렬화 때 RuntimeTypeModel 사용한 protobuffer 통해. 파생 된 유형으로 방출 된 유형을 하위 클래스로 분류하는 데는 아무런 문제가 없습니다.

나는 TYPEA 대신 인스턴스의 유형을 추가하는 데 필요한 :

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

을 ... 내가 가진 전에 : 물론, 순환 오류를 반환,

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

.

앞으로 도움이되기를 바랍니다.