Esempio n. 1
0
        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);
            }
        }
Esempio n. 2
0
        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);
                }
            }
        }
Esempio n. 3
0
        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);
            }
        }
Esempio n. 4
0
        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);
                    }
                }
            }
        }