1.先看如何调用,以及类的定义
执行结果如下:
生成代码类的代码如下:
public class AopFactory { public static I CreateAopObj<I, T>() where T : class, new() where I : class { return AopCreater<I, T>.Create(); } public class AopCreater<I, T> where T : class, new() where I : class { public static Func<I> Create = CreateAopObj(); private static Func<I> CreateAopObj() { //动态生成 var typeT = typeof(T); var typeI = typeof(I); AssemblyName asmName = new AssemblyName("ILGratorTest"); //创建程序集 var asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, System.Reflection.Emit.AssemblyBuilderAccess.RunAndSave); //创建模块 var module = asmBuilder.DefineDynamicModule(asmName.Name, asmName.Name + ".dll"); //生成代理类 var typeBuilder = module.DefineType(typeT.Name + "_Aop", TypeAttributes.Public, null, new Type[] { typeI }); //保存代理对象,并在构造函数的时候赋值 var aopObjField = typeBuilder.DefineField("aop_" + typeT.Name, typeT, FieldAttributes.Private); //生成构造函数 var tbCon = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes); var ilCon = tbCon.GetILGenerator(); ilCon.Emit(OpCodes.Ldarg_0); ilCon.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes)); ilCon.Emit(OpCodes.Ldarg_0); ilCon.Emit(OpCodes.Newobj, typeT.GetConstructor(Type.EmptyTypes)); ilCon.Emit(OpCodes.Stfld, aopObjField); ilCon.Emit(OpCodes.Ret); //获取要代理的方法 var methods = typeI.GetMethods(BindingFlags.SuppressChangeType | BindingFlags.Instance | BindingFlags.Public); //定义方法IL for (int i = 0; i < methods.Length; i++) { var currentMthod = methods[i]; var methodTypes = currentMthod.GetParameters().Select(d => d.ParameterType).ToArray(); var method = typeBuilder.DefineMethod(currentMthod.Name, MethodAttributes.Public | MethodAttributes.NewSlot | MethodAttributes.Virtual, currentMthod.ReturnType, methodTypes); //生成上下文对象 AopContext var methIl = method.GetILGenerator(); var localobjs = methIl.DeclareLocal(typeof(object[])); methIl.Emit(OpCodes.Ldc_I4, methodTypes.Length); methIl.Emit(OpCodes.Newarr, typeof(object)); methIl.Emit(OpCodes.Stloc, localobjs); for (int valIndex = 0; valIndex < methodTypes.Length; valIndex++) { //加载局部变量 methIl.Emit(OpCodes.Ldloc, localobjs); methIl.Emit(OpCodes.Ldc_I4, valIndex); methIl.Emit(OpCodes.Ldarg, valIndex + 1); if (methodTypes[valIndex].IsValueType) methIl.Emit(OpCodes.Box, methodTypes[valIndex]); methIl.Emit(OpCodes.Stelem_Ref); } bool isNoReturn = true; //1.设置局部变量 var locContext = methIl.DeclareLocal(typeof(AopContext)); LocalBuilder locReturn = null; if (currentMthod.ReturnType != typeof(void)) { isNoReturn = false; locReturn = methIl.DeclareLocal(currentMthod.ReturnType); } methIl.Emit(OpCodes.Newobj, typeof(AopContext).GetConstructor(Type.EmptyTypes)); methIl.Emit(OpCodes.Stloc, locContext); //1.1保存参数值到上下文中 var fild = typeof(AopContext).GetField("Paramter"); methIl.Emit(OpCodes.Ldloc, locContext); methIl.Emit(OpCodes.Ldloc, localobjs); methIl.Emit(OpCodes.Stfld, fild); //2.找到方法上面的特性 var aopAttrType = typeof(AopAttribute); var methodBefore = aopAttrType.GetMethod("BeforeInvoke"); var methodAfter = aopAttrType.GetMethod("AfterInvoke"); var aopAttribute = typeT.GetMethod(currentMthod.Name).GetCustomAttributes().Where(d => aopAttrType.IsAssignableFrom(d.GetType())).Cast<AopAttribute>().OrderBy(d => d.Sort).ToArray(); List<LocalBuilder> listAopLocalBuilder = new List<LocalBuilder>(); for (int aopAIndex = 0; aopAIndex < aopAttribute.Length; aopAIndex++) { //定义局部变量生成他们 var attrType = (aopAttribute[aopAIndex]).GetType(); var locAttribute = methIl.DeclareLocal(attrType); methIl.Emit(OpCodes.Newobj, attrType.GetConstructor(Type.EmptyTypes)); methIl.Emit(OpCodes.Stloc, locAttribute); //调用局部变量的BeforeInvoke 方法 methIl.Emit(OpCodes.Ldloc, locAttribute); methIl.Emit(OpCodes.Ldloc, locContext); methIl.Emit(OpCodes.Callvirt, methodBefore); listAopLocalBuilder.Add(locAttribute); } #region 异常代码块 methIl.BeginExceptionBlock(); //3.执行原来的方法 //aopObjField methIl.Emit(OpCodes.Ldarg_0); methIl.Emit(OpCodes.Ldfld, aopObjField); for (int argIndex = 0; argIndex < methodTypes.Length; argIndex++) { methIl.Emit(OpCodes.Ldarg, argIndex + 1); } methIl.Emit(OpCodes.Call, currentMthod); //4.判断原方法是否有返回值 if (currentMthod.ReturnType != typeof(void)) { var fildReturn = typeof(AopContext).GetField("ReturnObj"); //保存返回值 methIl.Emit(OpCodes.Stloc, locReturn); methIl.Emit(OpCodes.Ldloc, locContext); methIl.Emit(OpCodes.Ldloc, locReturn); methIl.Emit(OpCodes.Stfld, fildReturn); } methIl.BeginCatchBlock(typeof(Exception)); //保存变量的值先 var exception = methIl.DeclareLocal(typeof(Exception)); methIl.Emit(OpCodes.Stloc, exception); var methodCath = aopAttrType.GetMethod("CatchInvoke"); var locAopExcption = methIl.DeclareLocal(typeof(AopException)); //生成异常对象 methIl.Emit(OpCodes.Newobj, typeof(AopException).GetConstructor(Type.EmptyTypes)); methIl.Emit(OpCodes.Stloc, locAopExcption); //设置他的属性 methIl.Emit(OpCodes.Ldloc, locAopExcption); methIl.Emit(OpCodes.Ldloc, exception); methIl.Emit(OpCodes.Stfld, typeof(AopException).GetField("Exception")); //调用异常方法 for (int aopAIndex2 = 0; aopAIndex2 < aopAttribute.Length; aopAIndex2++) { methIl.Emit(OpCodes.Ldloc, listAopLocalBuilder[aopAIndex2]); methIl.Emit(OpCodes.Ldloc, locAopExcption); methIl.Emit(OpCodes.Callvirt, methodCath); } methIl.EndExceptionBlock(); #endregion //调用AfterInvoke方法 for (int aopAIndex = 0; aopAIndex < aopAttribute.Length; aopAIndex++) { //调用局部变量的BeforeInvoke 方法 methIl.Emit(OpCodes.Ldloc, listAopLocalBuilder[aopAIndex]); methIl.Emit(OpCodes.Ldloc, locContext); methIl.Emit(OpCodes.Callvirt, methodAfter); } if (!isNoReturn) { methIl.Emit(OpCodes.Ldloc, locReturn); } methIl.Emit(OpCodes.Ret); } var builedType = typeBuilder.CreateType(); asmBuilder.Save(asmName.Name + ".dll"); var methoddy = new DynamicMethod("createNewObj", typeI, null); var il1 = methoddy.GetILGenerator(); il1.Emit(OpCodes.Newobj, builedType.GetConstructor(Type.EmptyTypes)); il1.Emit(OpCodes.Ret); return methoddy.CreateDelegate(typeof(Func<I>)) as Func<I>; } } }
生成的代理对象如下: