public void AfterIL(MethodAopInfo info, CustomAttribute attribute) { var assembly = info.Assembly; var method = info.Method; var ilProcessor = method.Body.GetILProcessor(); List <Instruction> lastInstructions = new List <Instruction>(); //CommonHelper.AddOrEditDictionary<ScanAopInfo>(dic, "point", point); int index = 0; foreach (var t in method.Parameters) { if (t.IsReturnValue == false && t.ParameterType.IsByReference == false) { index++; lastInstructions.Add(Instruction.Create(OpCodes.Ldloc_S, InstuctionsHelper.GetVariableDefinition(ilProcessor.Body.Variables, "bsf_Dictionary"))); lastInstructions.Add(Instruction.Create(OpCodes.Ldstr, t.Name)); lastInstructions.Add(Instruction.Create(OpCodes.Ldarg_S, t)); lastInstructions.Add(Instruction.Create(OpCodes.Call, assembly.MainModule.Import(typeof(BSF.Aop.SystemRuntime.Tool.CommonHelper).GetMethod("AddOrEditDictionary").MakeGenericMethod(InstuctionsHelper.LoadType(t.ParameterType))))); lastInstructions.Add(ilProcessor.Create(OpCodes.Nop)); } } //new AroundAopAttribute().After(info2); lastInstructions.Add(Instruction.Create(OpCodes.Newobj, assembly.MainModule.Import(InstuctionsHelper.LoadType(attribute.AttributeType).GetConstructor(Type.EmptyTypes)))); lastInstructions.Add(Instruction.Create(OpCodes.Ldloc_S, InstuctionsHelper.GetVariableDefinition(ilProcessor.Body.Variables, "bsf_AroundInfo"))); lastInstructions.Add(Instruction.Create(OpCodes.Callvirt, assembly.MainModule.Import(InstuctionsHelper.LoadType(attribute.AttributeType).GetMethod("After")))); var lastInstruction = method.Body.Instructions[method.Body.Instructions.Count - 1]; //插入指令 foreach (var i in lastInstructions) { ilProcessor.InsertBefore(lastInstruction, i); } }
public override void IL(ScanAopInfo info) { foreach (var method in info.Methods) { try { var assembly = method.Assembly; var attrs = CommonHelper.GetAttribute(method.Method.CustomAttributes, typeof(AroundAopAttribute).FullName); foreach (var attr in attrs) { //必须实现默认构造函数 if (InstuctionsHelper.LoadType(attr.AttributeType).GetConstructor(Type.EmptyTypes) == null) { throw new AopException(string.Format("Type:{0} 必须实现默认无参构造函数", attr.AttributeType.FullName)); } var ilProcessor = method.Method.Body.GetILProcessor(); ilProcessor.Body.InitLocals = true; assembly.MainModule.Import(attr.AttributeType.Resolve()); BeforeIL(method, attr); AfterIL(method, attr); //移除属性,下次不再注入 method.Method.CustomAttributes.Remove(attr); } } catch (Exception exp) { throw new AopException("AroundAopIL出错,方法:" + method.Method.FullName, exp); } } }
private void BeforeIL(MethodAopInfo info, CustomAttribute attribute) { var assembly = info.Assembly; var method = info.Method; var ilProcessor = method.Body.GetILProcessor(); //L_0001: newobj instance void[mscorlib] System.Collections.Generic.Dictionary`2 < string, object>::.ctor() var firstInstruction = ilProcessor.Body.Instructions.First(); List <Instruction> beforeInstructions = new List <Instruction>(); //Dictionary<string, object> _bsf_dic = new Dictionary<string, object>(); var dictype = assembly.MainModule.Import(typeof(System.Collections.Generic.Dictionary <string, object>)); ilProcessor.Body.Variables.Add(new VariableDefinition("bsf_Dictionary", dictype)); beforeInstructions.Add(ilProcessor.Create(OpCodes.Nop)); beforeInstructions.Add(ilProcessor.Create(OpCodes.Newobj, assembly.MainModule.Import(typeof(System.Collections.Generic.Dictionary <string, object>).GetConstructor(Type.EmptyTypes)))); beforeInstructions.Add(Instruction.Create(OpCodes.Stloc_S, InstuctionsHelper.GetVariableDefinition(ilProcessor.Body.Variables, "bsf_Dictionary"))); /* CommonHelper.AddOrEditDictionary<string>(dic, "a", a); * ldloc.0 * L_0008: ldstr "a" * L_000d: ldarg.1 * L_000e: call void [BSF.Aop]BSF.Aop.SystemRuntime.Tool.CommonHelper::AddOrEditDictionary<string>(class [mscorlib]System.Collections.Generic.Dictionary`2<string, object>, string, !!0) * L_0013: nop */ byte index = 0; foreach (var t in method.Parameters) { if (t.IsReturnValue == false && t.ParameterType.IsByReference == false)//排除return ref,out { index++; beforeInstructions.Add(Instruction.Create(OpCodes.Ldloc_S, InstuctionsHelper.GetVariableDefinition(ilProcessor.Body.Variables, "bsf_Dictionary"))); beforeInstructions.Add(Instruction.Create(OpCodes.Ldstr, t.Name)); beforeInstructions.Add(Instruction.Create(OpCodes.Ldarg_S, t)); beforeInstructions.Add(Instruction.Create(OpCodes.Call, assembly.MainModule.Import(typeof(BSF.Aop.SystemRuntime.Tool.CommonHelper).GetMethod("AddOrEditDictionary").MakeGenericMethod(InstuctionsHelper.LoadType(t.ParameterType))))); beforeInstructions.Add(ilProcessor.Create(OpCodes.Nop)); } } /* * var _bsf_around = new BSF.Aop.Attributes.AroundInfo(System.Reflection.MethodBase.GetCurrentMethod(), _bsf_dic, this); * L_002e: call class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetCurrentMethod() * L_0033: ldloc.0 * L_0034: ldarg.0 * L_0035: newobj instance void [BSF.Aop]BSF.Aop.Attributes.AroundInfo::.ctor(class [mscorlib]System.Reflection.MethodBase, class [mscorlib]System.Collections.Generic.Dictionary`2<string, object>, object) * L_003a: stloc.1 */ var dictype2 = assembly.MainModule.Import(typeof(BSF.Aop.Attributes.Around.AroundInfo)); ilProcessor.Body.Variables.Add(new VariableDefinition("bsf_AroundInfo", dictype2)); beforeInstructions.Add(Instruction.Create(OpCodes.Call, assembly.MainModule.Import(typeof(System.Reflection.MethodBase).GetMethod("GetCurrentMethod", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public)))); beforeInstructions.Add(Instruction.Create(OpCodes.Ldloc_S, InstuctionsHelper.GetVariableDefinition(ilProcessor.Body.Variables, "bsf_Dictionary"))); if (method.IsStatic == false) { beforeInstructions.Add(Instruction.Create(OpCodes.Ldarg_0)); beforeInstructions.Add(Instruction.Create(OpCodes.Newobj, assembly.MainModule.Import(typeof(BSF.Aop.Attributes.Around.AroundInfo).GetConstructor(new Type[] { typeof(System.Reflection.MethodBase), typeof(System.Collections.Generic.Dictionary <string, object>), typeof(object) })))); } else { beforeInstructions.Add(Instruction.Create(OpCodes.Newobj, assembly.MainModule.Import(typeof(BSF.Aop.Attributes.Around.AroundInfo).GetConstructor(new Type[] { typeof(System.Reflection.MethodBase), typeof(System.Collections.Generic.Dictionary <string, object>) })))); } beforeInstructions.Add(Instruction.Create(OpCodes.Stloc_S, InstuctionsHelper.GetVariableDefinition(ilProcessor.Body.Variables, "bsf_AroundInfo"))); /*new BSF.Aop.Attributes.AroundAopAttribute().Before(_bsf_around); * L_0096: newobj instance void [BSF.Aop]BSF.Aop.Attributes.AroundAopAttribute::.ctor() * L_009b: ldloc.1 * L_009c: callvirt instance void [BSF.Aop]BSF.Aop.Attributes.AroundAopAttribute::Before(class [BSF.Aop]BSF.Aop.Attributes.AroundInfo) * */ beforeInstructions.Add(Instruction.Create(OpCodes.Newobj, assembly.MainModule.Import(InstuctionsHelper.LoadType(attribute.AttributeType).GetConstructor(Type.EmptyTypes)))); beforeInstructions.Add(Instruction.Create(OpCodes.Ldloc_S, InstuctionsHelper.GetVariableDefinition(ilProcessor.Body.Variables, "bsf_AroundInfo"))); beforeInstructions.Add(Instruction.Create(OpCodes.Callvirt, assembly.MainModule.Import(InstuctionsHelper.LoadType(attribute.AttributeType).GetMethod("Before")))); /*a = CommonHelper.Convert<string>(info.Params["a"]); * L_003a: ldloc.1 * L_003b: callvirt instance class [mscorlib]System.Collections.Generic.Dictionary`2<string, object> [BSF.Aop]BSF.Aop.Attributes.AroundInfo::get_Params() * L_0040: ldstr "a" * L_0045: callvirt instance !1 [mscorlib]System.Collections.Generic.Dictionary`2<string, object>::get_Item(!0) * L_004a: call !!0 [BSF.Aop]BSF.Aop.SystemRuntime.Tool.CommonHelper::Convert<string>(object) * L_004f: starg.s a * */ foreach (var t in method.Parameters) { if (t.IsReturnValue == false && t.ParameterType.IsByReference == false) { beforeInstructions.Add(Instruction.Create(OpCodes.Ldloc_S, InstuctionsHelper.GetVariableDefinition(ilProcessor.Body.Variables, "bsf_AroundInfo"))); beforeInstructions.Add(Instruction.Create(OpCodes.Callvirt, assembly.MainModule.Import(typeof(BSF.Aop.Attributes.Around.AroundInfo).GetMethod("get_Params")))); beforeInstructions.Add(Instruction.Create(OpCodes.Ldstr, t.Name)); beforeInstructions.Add(Instruction.Create(OpCodes.Callvirt, assembly.MainModule.Import(typeof(System.Collections.Generic.Dictionary <string, object>).GetMethod("get_Item")))); beforeInstructions.Add(Instruction.Create(OpCodes.Call, assembly.MainModule.Import(typeof(BSF.Aop.SystemRuntime.Tool.CommonHelper).GetMethod("Convert").MakeGenericMethod(InstuctionsHelper.LoadType(t.ParameterType))))); beforeInstructions.Add(Instruction.Create(OpCodes.Starg_S, t)); } } //插入指令 foreach (var i in beforeInstructions) { ilProcessor.InsertBefore(firstInstruction, i); } }
private void PropertysIL(AssemblyDefinition assembly, TypeDefinition type) { //模板 var notifyPropertyTemplateType = assembly.MainModule.Import(typeof(NotifyPropertyTemplate)).Resolve(); //PropertyChangedEventHandler PropertyChanged = null; foreach (var f in notifyPropertyTemplateType.Fields) { var f2 = new FieldDefinition(f.Name, f.Attributes, f.FieldType); MapperHelper.CopyProperty(f, f2); f2.DeclaringType = type; f2.FieldType = InstuctionsHelper.Import(assembly, f.FieldType); type.Fields.Add(f2); } //public void add_PropertyChanged(PropertyChangedEventHandler value) //public void remove_PropertyChanged(PropertyChangedEventHandler value) //void NotifyPropertyChanged(string info) foreach (var m in notifyPropertyTemplateType.Methods) { if (m.IsConstructor) { continue; } var m2 = new MethodDefinition(m.Name, m.Attributes, m.ReturnType); MapperHelper.CopyProperty(m, m2); m2.DeclaringType = type; foreach (var p in m.Parameters) { m2.Parameters.Add(p); } foreach (var p in m2.Parameters) { p.ParameterType = InstuctionsHelper.Import(assembly, p.ParameterType); } foreach (var v in m2.Body.Variables) { v.VariableType = InstuctionsHelper.Import(assembly, v.VariableType); } foreach (var i in m2.Body.Instructions) { if (i.Operand != null) { if (i.Operand is FieldDefinition && type.Fields.FirstOrDefault(c => c.Name == (i.Operand as FieldDefinition).Name) != null) { i.Operand = type.Fields.FirstOrDefault(c => c.Name == (i.Operand as FieldDefinition).Name); } else { i.Operand = InstuctionsHelper.Import(assembly, i.Operand); } } } type.Methods.Add(m2); } //public event PropertyChangedEventHandler PropertyChanged; foreach (var e in notifyPropertyTemplateType.Events) { var e2 = new EventDefinition(e.Name, e.Attributes, e.EventType); MapperHelper.CopyProperty(e, e2); e2.DeclaringType = type; e2.AddMethod = type.Methods.FirstOrDefault(c => c.Name == e2.AddMethod.Name); e2.RemoveMethod = type.Methods.FirstOrDefault(c => c.Name == e2.RemoveMethod.Name); type.Events.Add(e2); } //属性注入 foreach (var p in type.Properties) { if (CommonHelper.HasAttribute(type.CustomAttributes, typeof(NoAopAttribute).FullName) == true) { continue; } if (p.SetMethod != null) { var method = p.SetMethod; var ilProcessor = method.Body.GetILProcessor(); var lastInstruction = method.Body.Instructions[method.Body.Instructions.Count - 1]; /* * ldarg.0 * L_0009: ldstr "CustomerName" * L_000e: call instance void BSF.Aop.Test.NotifyTest::NotifyPropertyChanged(string) * L_0013: nop * */ List <Instruction> lastInstructions = new List <Instruction>(); lastInstructions.Add(Instruction.Create(OpCodes.Ldarg_0)); lastInstructions.Add(Instruction.Create(OpCodes.Ldstr, p.Name)); lastInstructions.Add(Instruction.Create(OpCodes.Call, type.Methods.FirstOrDefault(c => c.Name == "NotifyPropertyChanged"))); lastInstructions.Add(Instruction.Create(OpCodes.Nop)); //插入指令 foreach (var i in lastInstructions) { ilProcessor.InsertBefore(lastInstruction, i); } } } }