Пример #1
0
        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));
        }
Пример #2
0
        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));
        }
Пример #3
0
        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());
        }
Пример #4
0
        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));
        }
Пример #5
0
        /// <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);
        }