public DynamicReadTravellerBuilder(MethodBuilder builder, SerializableType target, TravellerContext context) { _target = target; _context = context; _il = builder.IL; _visitorVariable = new MethodArgILCodeVariable(1, typeof(IReadVisitor)); }
public void BuildTraveller() { if (_classBuilder.IsSealed) { throw new InvalidOperationException("Classification builder is sealed"); } var target = _typeProvider.GetOrCreate(_type); var members = _dtContext.Members; var factoryArgument = new ILArgPointer(members.VisitArgsFactoryType, 1); var childTravellers = new Dictionary <Type, ChildTravellerInfo>(); var argFields = new Dictionary <SerializableProperty, FieldInfo>(); var il = _constructorBuilder.IL; var travellerIndex = 0; foreach (var property in target.Properties) { var argField = _classBuilder.DefinePrivateField("_arg" + property.Ref.Name, members.VisitArgsType); var visitArgsCode = new ILCallMethodSnippet(factoryArgument, members.ConstructVisitArgsMethod, property.Ref.Name); il.Set(ILPointer.This(), argField, visitArgsCode); argFields.Add(property, argField); if (!ReflectionAnalyzer.TryGetComplexTypes(property.Ext, out var types)) { continue; } foreach (var type in types) { if (childTravellers.ContainsKey(type)) { continue; } var dynamicTraveller = _dtContext.Get(type); var interfaceType = typeof(IGraphTraveller <>).MakeGenericType(type); var fieldBuilder = _classBuilder.DefinePrivateField(string.Concat("_traveller", type.Name, ++travellerIndex), interfaceType); childTravellers.Add(type, new ChildTravellerInfo { Field = fieldBuilder, TravelWriteMethod = dynamicTraveller.TravelWriteMethod, TravelReadMethod = dynamicTraveller.TravelReadMethod }); var getFactoryCode = ILSnippet.Call(factoryArgument, members.ConstructVisitArgsWithTypeMethod, type); var newTraveller = ILPointer.New(dynamicTraveller.Constructor, getFactoryCode); il.Set(ILPointer.This(), fieldBuilder, newTraveller); } } il.Emit(OpCodes.Ret); var context = new TravellerContext(childTravellers, argFields); BuildWriteMethods(target, context); BuildReadMethods(target, context); _classBuilder.Seal(); DynamicTraveller.Complete(_classBuilder.Type); }
public DynamicReadTravellerBuilder(MethodBuilder builder, SerializableType target, TravellerContext context, ITypeProvider typeProvider) { _target = target; _context = context; _typeProvider = typeProvider; _il = builder.IL; _visitorVariable = new ILArgPointer(typeof(IReadVisitor), 1); }
private void BuildReadMethods(SerializableType target, TravellerContext context) { var typedMethodBuilder = _travelReadMethod; var readBuilder = new DynamicReadTravellerBuilder(typedMethodBuilder, target, context, _typeProvider.Provider); readBuilder.BuildTravelReadMethod(); var untypedMethodBuilder = _classBuilder.DefineOverloadMethod("Travel", typeof(void), new[] { typeof(IReadVisitor), typeof(object) }); var il = untypedMethodBuilder.IL; il.InvokeMethod(ILPointer.This(), typedMethodBuilder.Method, ILPointer.Arg(1, typeof(IReadVisitor)), ILPointer.Arg(2, typeof(object)).Cast(target.Type)); il.Emit(OpCodes.Ret); }
public void BuildTraveller() { if (_classBuilder.IsSealed) throw new InvalidOperationException("Class builder is sealed"); var target = _typeProvider.GetOrCreate(_type); var members = _dtContext.Members; var factoryArgument = new MethodArgILCodeVariable(1, members.VisitArgsFactoryType); var childTravellers = new Dictionary<Type, ChildTravellerInfo>(); var argFields = new Dictionary<SerializableProperty, FieldInfo>(); var travellerIndex = 0; foreach (var property in target.Properties) { var argField = _classBuilder.DefinePrivateField("_arg" + property.Ref.Name, members.VisitArgsType); var visitArgsCode = new CallMethodILCode(factoryArgument, members.ConstructVisitArgsMethod, property.Ref.Name); _constructorBuilder.IL.SetField(argField, visitArgsCode); argFields.Add(property, argField); Type[] types; if (!ReflectionAnalyzer.TryGetComplexTypes(property.Ext, out types)) continue; foreach (var type in types) { if (childTravellers.ContainsKey(type)) continue; var dynamicTraveller = _dtContext.Get(type); var interfaceType = typeof (IGraphTraveller<>).MakeGenericType(type); var fieldBuilder = _classBuilder.DefinePrivateField(string.Concat("_traveller", type.Name, ++travellerIndex), interfaceType); childTravellers.Add(type, new ChildTravellerInfo { Field = fieldBuilder, TravelWriteMethod = dynamicTraveller.TravelWriteMethod, TravelReadMethod = dynamicTraveller.TravelReadMethod }); var getFactoryCode = new CallMethodILCode(factoryArgument, members.ConstructVisitArgsWithTypeMethod, type); var callConstructorCode = new CallConstructorILCode(dynamicTraveller.Constructor, getFactoryCode); _constructorBuilder.IL.SetField(fieldBuilder, callConstructorCode); //_constructorBuilder.IL.SetField(fieldBuilder, dynamicTraveller.Constructor); } } _constructorBuilder.IL.Return(); var context = new TravellerContext(childTravellers, argFields); BuildWriteMethods(target, context); BuildReadMethods(target, context); _classBuilder.Seal(); _dynamicTraveller.Complete(_classBuilder.Type); }
private void BuildWriteMethods(SerializableType target, TravellerContext context) { var typedMethodBuilder = _travelWriteMethod; var writeBuilder = new DynamicWriteTravellerBuilder(typedMethodBuilder, target, context); writeBuilder.BuildTravelWriteMethod(); var untypedMethodBuilder = _classBuilder.DefineOverloadMethod("Travel", typeof(void), new[] { typeof(IWriteVisitor), typeof(object) }); var il = untypedMethodBuilder.IL; il.LoadThis(); il.Var.Load(new MethodArgILCodeVariable(1, typeof(IWriteVisitor))); il.Var.Load(new MethodArgILCodeVariable(2, typeof(object))); il.Cast(target.Type); il.Call(typedMethodBuilder.Method); il.Return(); }