public void BuildEmitMethod(Expression <Func <TAggregateRoot, object> > func)
        {
            var    propertyName = func.GetMember().Name;
            var    entityType   = typeof(TAggregateRoot);
            Type   parmType     = typeof(object);
            string methodName   = "set_" + propertyName;
            var    callMethod   = entityType.GetMethod(methodName,
                                                       BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic);
            var           para   = callMethod.GetParameters()[0];
            DynamicMethod method = new DynamicMethod("EmitCallable", null, new Type[] { entityType, parmType },
                                                     entityType.Module);
            var il    = method.GetILGenerator();
            var local = il.DeclareLocal(para.ParameterType, true);

            il.Emit(OpCodes.Ldarg_1);
            if (para.ParameterType.IsValueType)
            {
                il.Emit(OpCodes.Unbox_Any, para.ParameterType);
            }
            else
            {
                il.Emit(OpCodes.Castclass, para.ParameterType);
            }
            il.Emit(OpCodes.Stloc, local);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldloc, local);
            il.EmitCall(OpCodes.Callvirt, callMethod, null);
            il.Emit(OpCodes.Ret);

            EmitSetValue = method.CreateDelegate(typeof(SetValueDelegateHandler)) as SetValueDelegateHandler;
        }
예제 #2
0
        public void SetPropertyValueEmit(Type entityType, string propertyName)
        {
            //Type entityType = entity.GetType();
            Type parmType = typeof(object);
            // 指定函数名
            string methodName = "set_" + propertyName;
            // 搜索函数,不区分大小写 IgnoreCase
            var callMethod = entityType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic);
            // 获取参数
            var para = callMethod.GetParameters()[0];
            // 创建动态函数
            DynamicMethod method = new DynamicMethod("EmitCallable", null, new Type[] { entityType, parmType }, entityType.Module);
            // 获取动态函数的 IL 生成器
            var il = method.GetILGenerator();
            // 创建一个本地变量,主要用于 Object Type to Propety Type
            var local = il.DeclareLocal(para.ParameterType, true);

            // 加载第 2 个参数【(T owner, object value)】的 value
            il.Emit(OpCodes.Ldarg_1);
            if (para.ParameterType.IsValueType)
            {
                il.Emit(OpCodes.Unbox_Any, para.ParameterType);// 如果是值类型,拆箱 string = (string)object;
            }
            else
            {
                il.Emit(OpCodes.Castclass, para.ParameterType); // 如果是引用类型,转换 Class = object as Class
            }
            il.Emit(OpCodes.Stloc, local);                      // 将上面的拆箱或转换,赋值到本地变量,现在这个本地变量是一个与目标函数相同数据类型的字段了。
            il.Emit(OpCodes.Ldarg_0);                           // 加载第一个参数 owner
            il.Emit(OpCodes.Ldloc, local);                      // 加载本地参数
            il.EmitCall(OpCodes.Callvirt, callMethod, null);    //调用函数
            il.Emit(OpCodes.Ret);                               // 返回

            /* 生成的动态函数类似:
             * void EmitCallable(T owner, object value)
             * {
             * T local = (T)value;
             * owner.Method(local);
             * }
             */

            EmitSetValue = method.CreateDelegate(typeof(SetValueDelegateHandler)) as SetValueDelegateHandler;
        }