private EmitHelper RegisterProperty(DynamicFieldBuilder fieldBuilder, EmitHelper emiter, IProperty property) { var local = emiter.DeclareLocal(property.GetType()); return(emiter .ldtoken(InnerBuilder.UnderlyingSystemType) .call(TypeGetTypeFromHandle) .ldstr($"{assemblyBuilder.AssemblyName}-{TypeName}:{property.Name}") .call(GetPropertyMethod) .stloc(local) .Assert( property is IPropertyReference, e => { var p = property.As <IPropertyReference>().Reference; var dynamicFieldBuilder = fields.FirstOrDefault(s => s.FieldName == GetFieldName(p)); if (dynamicFieldBuilder != null) { var field = Properties.Contains(p) ? dynamicFieldBuilder.FieldBuilder : p.EntityType.GetFields(BindingFlags.Public | BindingFlags.Static).FirstOrDefault(s => s.Name == GetFieldName(p)); if (field != null) { e.ldloc(local).ldsfld(field).call(SetReferenceMethod); } } }) .ldloc(local) .call(RegisterMethod) .stsfld(fieldBuilder.FieldBuilder)); }
private EmitHelper RegisterProperty(DynamicFieldBuilder fieldBuilder, EmitHelper emiter, IProperty property) { var local = emiter.DeclareLocal(property.GetType()); var b = InnerBuilder.DefineMethod( "??_" + property.Name, typeof(IProperty), null, VisualDecoration.Private, CallingDecoration.Static, #if NET35 x => { var @delegate = MakeLambdaExpression(property).Compile(); if (@delegate != null) { var bytes = @delegate.Method.GetMethodBody().GetILAsByteArray(); x.MethodBuilder.MethodBuilder.CreateMethodBody(bytes, bytes.Length); } }); #elif NETSTANDARD2_0 x => { }); //todo #else x => MakeLambdaExpression(property).CompileToMethod(x.MethodBuilder.MethodBuilder)); #endif return(emiter .ldtoken(InnerBuilder.UnderlyingSystemType) .call(TypeGetTypeFromHandle) .call(b.MethodBuilder) .stloc(local) .Assert( property is IPropertyReference, e => { var p = property.As <IPropertyReference>().Reference; var dynamicFieldBuilder = fields.FirstOrDefault(s => s.FieldName == GetFieldName(p)); if (dynamicFieldBuilder != null) { var field = Properties.Contains(p) ? dynamicFieldBuilder.FieldBuilder : p.EntityType.GetFields(BindingFlags.Public | BindingFlags.Static).FirstOrDefault(s => s.Name == GetFieldName(p)); if (field != null) { e.ldloc(local).ldsfld(field).call(SetReferenceMethod); } } }) .ldloc(local) .call(RegisterMethod) .stsfld(fieldBuilder.FieldBuilder)); }
private static Type InternalCreateType(IDataReader reader, IEnumerable <Type> implInterfaceTypes) { var guid = Guid.NewGuid().ToString("N"); var typeBuilder = new DynamicAssemblyBuilder("_Dynamic_" + guid).DefineType("$<>" + guid); foreach (var type in implInterfaceTypes) { typeBuilder.ImplementInterface(type); } var length = reader.FieldCount; var fields = new DynamicFieldBuilder[length]; for (var i = 0; i < length; i++) { var name = GetFieldName(reader.GetName(i)); var type = reader.GetFieldType(i); var fieldBuilder = typeBuilder.DefineField("<>__" + name, type); typeBuilder.DefineProperty(name, type).DefineGetSetMethods(fieldBuilder); fields[i] = fieldBuilder; } var constructorBuilder = typeBuilder.DefineConstructor(new[] { typeof(IDataReader), typeof(IRecordWrapper) }, ilCoding: bc => bc.Emitter .For(0, length, (e, i) => e.ldarg_0 .ldarg_2 .ldarg_1 .ldc_i4(i) .callvirt(RecordWrapHelper.GetGetValueMethod(reader.GetFieldType(i))) .stfld(fields[i].FieldBuilder)) .ret()); constructorBuilder.DefineParameter("reader"); constructorBuilder.DefineParameter("wrapper"); return(typeBuilder.CreateType()); }
private EmitHelper RegisterProperty(DynamicFieldBuilder fieldBuilder, EmitHelper emiter, IProperty property) { var local = emiter.DeclareLocal(property.GetType()); if (property is GeneralProperty) { emiter = InitGeneralPropertyInfo(emiter, local, property); } else if (property is RelationProperty) { emiter = InitRelationProperty(emiter, local, property); } else if (property is PropertyExtension ext) { return(RegisterProperty(fieldBuilder, emiter, ext.Property)); } else { emiter = emiter.ldnull; } return(emiter.stsfld(fieldBuilder.FieldBuilder)); }
/// <summary> /// 向属性的 set 方法中注入代码。 /// </summary> /// <param name="builder"></param> /// <param name="field"></param> /// <param name="globalIntercepts"></param> /// <param name="interceptMethod"></param> /// <param name="property"></param> /// <param name="method"></param> /// <returns></returns> private static DynamicMethodBuilder InjectSetMethod(DynamicTypeBuilder builder, DynamicFieldBuilder field, IList <InterceptAttribute> globalIntercepts, DynamicMethodBuilder interceptMethod, PropertyInfo property, MethodInfo method) { var attributes = property.GetCustomAttributes <InterceptAttribute>(true).Union(globalIntercepts); var isInterface = builder.BaseType == typeof(object); var initMethod = DefineInitializeMethod(builder, method.Name); var parameters = method.GetParameters(); var methodBuilder = builder.DefineMethod( method.Name, method.ReturnType, (from s in parameters select s.ParameterType).ToArray(), ilCoding: ctx => { var lblCancel = ctx.Emitter.DefineLabel(); ctx.Emitter.DeclareLocal(); ctx.Emitter.InitInterceptors(attributes); ctx.Emitter.InitLocal(property, method); ctx.Emitter.BeginExceptionBlock(); ctx.Emitter.CallInitialize(initMethod) .CallInterceptors(interceptMethod, InterceptType.BeforeSetValue) .ldloc(STACK_CALLINFO_INDEX) .callvirt(InterceptCache.CallInfoGetCancel).brtrue_s(lblCancel) .Assert(isInterface, c => c.ldarg_0.ldarg_1.stfld(field.FieldBuilder), c => c.ldarg_0.GetArguments(property.PropertyType, 0).call(method)) .MarkLabel(lblCancel) .CallInterceptors(interceptMethod, InterceptType.AfterSetValue) .BeginCatchBlock(typeof(Exception)) .SetException() .CallInterceptors(interceptMethod, InterceptType.Catching) .Assert(AllowThrowException(attributes), e => e.ThrowException()) .BeginFinallyBlock() .CallInterceptors(interceptMethod, InterceptType.Finally) .EndExceptionBlock() .ret(); }); foreach (var par in parameters) { methodBuilder.DefineParameter(par.Name); } return(methodBuilder); }