Ejemplo n.º 1
0
        public void add1(int x, int y, string z)
        {
            Type           type            = GetType();
            ProxyAttribute customAttribute = type.GetCustomAttribute <ProxyAttribute>();

            if (customAttribute != null)
            {
                customAttribute.AfterCall();
            }
            Console.WriteLine("结果:" + (this.me + x + y + Convert.ToInt32(z)));
        }
Ejemplo n.º 2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sourceType">源类型</param>
        /// <param name="interfaceType">源类型实现的接口(规范)</param>
        /// <returns>代理类型</returns>
        public static Type ProxyTypeBuilder(Type sourceType, Type interfaceType)
        {
            if (!interfaceType.IsInterface)
            {
                throw new Exception("不是接口类型");
            }

            if (!sourceType.IsClass)
            {
                throw new Exception("不是Class类型");
            }

            TypeBuilder defClassBuilder = CreateDynamicTypeBuild(sourceType.Name + "Proxy");

            defClassBuilder.AddInterfaceImplementation(interfaceType);


            #region 编写字段 代理字段

            FieldBuilder _testfb = defClassBuilder.DefineField("_" + sourceType.Name, sourceType, FieldAttributes.Private);

            #endregion

            #region 编写构造 默认模式

            var constructor           = sourceType.GetConstructors()[0];
            var sourceTypeCP          = constructor.GetParameters().Select(o => o.ParameterType);
            var constructorParameters = new List <Type>();
            //constructorParameters.Add(sourceType);

            constructorParameters.AddRange(sourceTypeCP);
            ConstructorBuilder dfltConstrBld = defClassBuilder.DefineConstructor(
                MethodAttributes.Public,
                CallingConventions.HasThis,
                constructorParameters.ToArray()
                );
            var constructorIL = dfltConstrBld.GetILGenerator();

            LocalBuilder _obj = constructorIL.DeclareLocal(sourceType);

            for (short i = 0; i < constructorParameters.Count; i++)
            {
                constructorIL.Emit(OpCodes.Ldarg, i + 1);
            }
            constructorIL.Emit(OpCodes.Newobj, sourceType.GetConstructor(sourceTypeCP.ToArray()));
            constructorIL.Emit(OpCodes.Stloc, _obj);//局部变量赋值


            constructorIL.Emit(OpCodes.Ldarg_0);     //this
            constructorIL.Emit(OpCodes.Ldloc, _obj); //局部变量入栈
            constructorIL.Emit(OpCodes.Stfld, _testfb);

            constructorIL.Emit(OpCodes.Ret); //函数返回
            #endregion

            #region 编写构造 注入模式

            ConstructorBuilder ConstrBld_1 = defClassBuilder.DefineConstructor(
                MethodAttributes.Public,
                CallingConventions.HasThis,
                new Type[] { sourceType }
                );
            var ConstrBld_IL = ConstrBld_1.GetILGenerator();

            ConstrBld_IL.Emit(OpCodes.Ldarg_0); //this
            ConstrBld_IL.Emit(OpCodes.Ldarg_1); //
            ConstrBld_IL.Emit(OpCodes.Stfld, _testfb);
            ConstrBld_IL.Emit(OpCodes.Ret);     //函数返回
            #endregion

            #region 定义方法
            var Methods = interfaceType.GetMethods();
            //排除obj基类方法
            var methods = Methods.Where(m => m.Name != "GetHashCode" || m.Name != "Equals" || m.Name != "ToString" || m.Name != "ReferenceEquals");

            foreach (var method in methods)
            {
                ProxyAttribute proxyAttribute = null;
                var            attributes     = method.GetCustomAttributes(true);
                var            attribute      = attributes.FirstOrDefault(o => { return(o is ProxyAttribute); });
                if (attribute != null)
                {
                    proxyAttribute = (ProxyAttribute)attribute;
                }
                //定义一个方法
                var parameterTypes = method.GetParameters().Select(o => o.ParameterType).ToArray();
                var methodBldr     = defClassBuilder.DefineMethod(method.Name,
                                                                  MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual,
                                                                  method.ReturnType,
                                                                  parameterTypes
                                                                  );
                Expression <Func <int, int, string, int> > add = (x, y, z) => 1 + 2;
                //add.CompileToMethod(methodBldr);

                ILGenerator ilOfShow = methodBldr.GetILGenerator();

                //方法调之前

                LocalBuilder returnType = ilOfShow.DeclareLocal(method.ReturnType);
                //非静态方法参数索引从1开始
                //ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
                #region  调用方法之前
                //ilOfShow.Emit(OpCodes.Ldarg_1);
                //ilOfShow.Emit(OpCodes.Ldarg_2);
                //ilOfShow.Emit(OpCodes.Add)
                //ilOfShow.Emit(OpCodes.Ldstr, "调用方法之前");
                //ilOfShow.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
                if (proxyAttribute != null)
                {
                    ilOfShow.Emit(OpCodes.Newobj, proxyAttribute.GetType().GetConstructor(new Type[0]));
                    ilOfShow.Emit(OpCodes.Call, proxyAttribute.GetType().GetMethod("AfterCall", new Type[0]));
                    //ilOfShow.Emit(OpCodes.Pop);
                }

                #endregion

                #region 调用方法等同于  ReturnType result= method(arg1,arg2,....);
                ilOfShow.Emit(OpCodes.Ldarg_0);
                ilOfShow.Emit(OpCodes.Ldfld, _testfb);
                for (short i = 0; i < parameterTypes.Length; i++)
                {
                    ilOfShow.Emit(OpCodes.Ldarg, i + 1);
                }
                //ilOfShow.Emit(OpCodes.Ldarg_1);
                //ilOfShow.Emit(OpCodes.Ldarg_2);

                ilOfShow.Emit(OpCodes.Call, sourceType.GetMethod(method.Name, parameterTypes));
                ilOfShow.Emit(OpCodes.Stloc, returnType);//赋值语句
                #endregion

                #region  调用方法之后
                //ilOfShow.Emit(OpCodes.Ldstr, "调用方法之后");
                //ilOfShow.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
                if (proxyAttribute != null)
                {
                    ilOfShow.Emit(OpCodes.Newobj, proxyAttribute.GetType().GetConstructor(new Type[0]));
                    ilOfShow.Emit(OpCodes.Call, proxyAttribute.GetType().GetMethod("AfterCall", new Type[0]));
                    //ilOfShow.Emit(OpCodes.Pop);
                }
                #endregion
                ilOfShow.Emit(OpCodes.Ldloc, returnType); //加载局部变量
                ilOfShow.Emit(OpCodes.Ret);               //函数返回
            }

            #endregion

            Type t = defClassBuilder.CreateType();
            assemblyBuilder.Save("MyClass.dll");
            //assembly = assemblyBuilder.
            return(t);
        }