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; }
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; }