• 对于java的应用,一个类要加上动态代理,可以加入关键字reflection的动态代理(Dynamic Proxy),随便可以搜到很多咚咚。
  • 那么如何在.NET下面实现呢?MSDN上翻译了一篇文章,代码不难,主要是应用了Emit以及Reflection来实现,但由于里面出现了一段IL交互的代码,让我惊异了一下,在Assembly里面原来可以如此轻易的控制IL的动态代码[生成编程(Generative Programming),这里有点CodeDom的链接,把算法搞定回来研究下]加入!MS真的很强呀!加上P/Invoke,和unsafe开关,IL的evalation栈。Net平台真的是一个集大成者!再次崇拜之![虽然JAVA也有本地方法还有SWT之类的本地交互模式,但SWT只是通过本地方法来实现与宿主的界面一致性,而比如openGL之类的接口则需要根据平台再编写相关接口。似乎这样说,对JAVA不公平,因为要想实现彻底的跨平台,是不可能兼顾到很多东西的!或许是本人对java天生排斥吧,因为看过java5所谓的多线程界面实现和在J2ME上的线程模拟,无论从稳定性还是从性能上和。NET相去较远!不过都很强,都是LLV的学习榜样,加油了]
  • 把代码实现了一遍,写蓝屏了,小郁闷了下!

namespace DynamicProxy
{//动态挂接类,他们貌似叫什么拦截器;java里面的webservice有一m多与服务器serlvet交互的拦截器,俄!~~这个名字没有一点美感!
    public class Interceptor
    {
        public Object Call(String methodName, MulticastDelegate methodDelegate, params Object[] args)
        {
            Console.WriteLine("In interceptor side");
            return methodDelegate.Method.Invoke(methodDelegate.Target, args);
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;

//Notes: orlando try to use Reflection to implement dynamic proxy technology.

namespace DynamicProxy
{
    public class Class1
    {
        public virtual void MyMethod()
        {
            Console.WriteLine("in Class1 MyMethod()");
        }
    }

    class Program
    {
        private ModuleBuilder m_Module;
        private AssemblyBuilder m_Assembly;

        //for type and typebuilder
        private Type m_Type;
        private TypeBuilder m_TypeBuilder;

        //for proxy class
        private TypeBuilder[] m_NestedTypeBuilders;
        private ConstructorBuilder[] m_NestedTypeConstructors;
        private ConstructorBuilder m_ConstructorBuilder;
        private FieldBuilder m_Interceptor;

        /// <summary>
        /// Generates the delegate class.
        /// </summary>
        private void GenerateDelegateClass()
        {
            MethodInfo[] methodInfos = m_Type.GetMethods();//get all public method for target of delegation
            m_NestedTypeBuilders = new TypeBuilder[methodInfos.Length];
            m_NestedTypeConstructors = new ConstructorBuilder[methodInfos.Length];
            //for each method, create embedded class
            for (Int32 i = 0; i < m_NestedTypeBuilders.Length; i++)
            {
                //Nested Class
                m_NestedTypeBuilders[i] = m_TypeBuilder.DefineNestedType("__" + methodInfos[i].Name + "__delegate", TypeAttributes.NestedPrivate | TypeAttributes.Sealed, typeof(MulticastDelegate));
                //Constructor of Nested class  
                m_NestedTypeConstructors[i] = m_NestedTypeBuilders[i].DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { typeof(Object), typeof(IntPtr) });
                m_NestedTypeConstructors[i].SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed);

                Type[] argsType = GetParameterTypes(methodInfos[i]);
                //在这个Nested Class中加入一个在运行时(runtime)管理的Invoke方法
                MethodBuilder mb = m_NestedTypeBuilders[i].DefineMethod("Invoke", MethodAttributes.Public, CallingConventions.Standard, methodInfos[i].ReturnType, argsType);
                mb.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed);
            }
        }

        /// <summary>
        /// Gets the parameter types.
        /// </summary>
        /// <param name="methodInfo">The method info.</param>
        /// <returns></returns>
        private Type[] GetParameterTypes(MethodInfo methodInfo)
        {
            ParameterInfo[] args = methodInfo.GetParameters();
            Type[] argsType = new Type[args.Length];
            for (Int32 j = 0; j < args.Length; j++) { argsType[j] = args[j].ParameterType; }
            return argsType;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Program"/> class.
        /// </summary>
        public Program()
        {
            AppDomain domain = AppDomain.CurrentDomain;//System.Threading.Thread.GetDomain();
            AssemblyName asmName = new AssemblyName("DynamicModule");
            m_Assembly = domain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);
            m_Module = m_Assembly.DefineDynamicModule("Module", "Func.dll");//save into local disk
        }

        /// <summary>
        /// Generates the type.
        /// </summary>
        private void GenerateType()
        {//m_Type from?
            m_TypeBuilder = m_Module.DefineType(m_Type.Name + "_" + m_Type.GetHashCode().ToString(), TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed, m_Type);
        }

        private FieldBuilder[] m_MultiCastDelegates;

        /// <summary>
        /// Generates the fields.
        /// </summary>
        private void GenerateFields()
        {
            //__Interceptor parameter, using Interceptor class to implement the method.
            m_Interceptor = m_TypeBuilder.DefineField("__Interceptor", typeof(Interceptor), FieldAttributes.Private);
            //__dynamic fields of private attributes
            MethodInfo[] methodInfos = m_Type.GetMethods();
            m_MultiCastDelegates = new FieldBuilder[methodInfos.Length];
            for (Int32 i = 0; i < methodInfos.Length; i++)
            {
                m_MultiCastDelegates[i] = m_TypeBuilder.DefineField(methodInfos[i].Name + "_field", m_NestedTypeBuilders[i], FieldAttributes.Private);
            }
        }

        private MethodBuilder[] m_CallBackMethods;

        /// <summary>
        /// Generates the call back methods.
        /// </summary>
        private void GenerateCallBackMethods()
        {
            MethodInfo[] methodInfos = m_Type.GetMethods();
            m_CallBackMethods = new MethodBuilder[methodInfos.Length];
            for (Int32 i = 0; i < methodInfos.Length; i++)
            {
                Type[] argTypes = GetParameterTypes(methodInfos[i]); // 得到当前方法所有参数的Type
                m_CallBackMethods[i] = m_TypeBuilder.DefineMethod("callback_" + methodInfos[i].Name, MethodAttributes.Private, CallingConventions.Standard, methodInfos[i].ReturnType, argTypes); //定义回调方法
                //得到IL的产生器
                ILGenerator ilGenerator = m_CallBackMethods[i].GetILGenerator();
                ilGenerator.Emit(OpCodes.Ldarg_0);  // 将代理类的引用压入evaluation栈
                for (Int32 j = 0; j < argTypes.Length; j++)//push stack for parameters
                {
                    ilGenerator.Emit(OpCodes.Ldarg, j + 1); //将回调函数的每一个参数压入evaluation栈
                }
                ilGenerator.Emit(OpCodes.Call, methodInfos[i]); //调用父类的方法
                ilGenerator.Emit(OpCodes.Ret); //返回,好好研究下这段
            }
        }

        private void GenerateOverrideMethods()
        {
            MethodInfo[] methodInfos = m_Type.GetMethods();
            for (Int32 i = 0; i < methodInfos.Length; i++){
                Type[] argTypes = GetParameterTypes(methodInfos[i]);
                MethodBuilder mb = m_TypeBuilder.DefineMethod(methodInfos[i].Name, MethodAttributes.Public | MethodAttributes.Virtual,
                       CallingConventions.Standard,   methodInfos[i].ReturnType,  argTypes); //定义override方法

                ILGenerator ilGenerator = mb.GetILGenerator();
                //将m_Interceptor变量压入栈
                ilGenerator.Emit(OpCodes.Ldarg_0);
                ilGenerator.Emit(OpCodes.Ldfld, m_Interceptor);
                //将Call的第一个参数压栈
                ilGenerator.Emit(OpCodes.Ldstr, methodInfos[i].Name);
                //将Call的第二个参数压栈
                ilGenerator.Emit(OpCodes.Ldarg_0);
                ilGenerator.Emit(OpCodes.Ldfld, m_MultiCastDelegates[i]);
                //将Call的第三个参数压栈
                LocalBuilder local = ilGenerator.DeclareLocal(typeof(Object[]));
                ilGenerator.Emit(OpCodes.Ldc_I4, argTypes.Length);
                ilGenerator.Emit(OpCodes.Newarr, typeof(Object));
                ilGenerator.Emit(OpCodes.Stloc, local);
                ilGenerator.Emit(OpCodes.Ldloc, local);
                for (Int32 j = 0; j < argTypes.Length; j++)
                {
                    ilGenerator.Emit(OpCodes.Ldc_I4, j);
                    ilGenerator.Emit(OpCodes.Ldarg, j + 1);
                    ilGenerator.Emit(OpCodes.Box, argTypes[j]);
                    ilGenerator.Emit(OpCodes.Stelem_Ref);
                    ilGenerator.Emit(OpCodes.Ldloc, local);
                }

                //调用Call方法, Call Interceptor’s Call Method
                ilGenerator.Emit(OpCodes.Call, typeof(Interceptor).GetMethod("Call", new Type[] { typeof(String), typeof(MulticastDelegate), typeof(Object[]) }));
                if (methodInfos[i].ReturnType.Equals(typeof(void)))
                {
                    ilGenerator.Emit(OpCodes.Pop); //如果override方法返回void, 将Call返回的null出栈
                }
                else
                {
                    //将返回值是值类型(value type)时拆箱(Unbox)
                    ilGenerator.Emit(OpCodes.Unbox_Any, methodInfos[i].ReturnType);
                }
                ilGenerator.Emit(OpCodes.Ret);

            }
        }

        private void GenerateConstructor()
        {
            m_ConstructorBuilder = m_TypeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { typeof(Interceptor) });
           ILGenerator ilGenerator = m_ConstructorBuilder.GetILGenerator();
            //调用父类构造函数(假设父类只有无参数的构造函数)
            ilGenerator.Emit(OpCodes.Ldarg_0);
            ilGenerator.Emit(OpCodes.Call, m_Type.GetConstructor(new Type[] { }));

            // 初始化__Interceptor变量
            ilGenerator.Emit(OpCodes.Ldarg_0);
            ilGenerator.Emit(OpCodes.Ldarg_1);
            ilGenerator.Emit(OpCodes.Stfld, m_Interceptor);

            // 初始化Nested Class变量
            for (Int32 i = 0; i < m_MultiCastDelegates.Length; i++)
            {
                ilGenerator.Emit(OpCodes.Ldarg_0);
                ilGenerator.Emit(OpCodes.Ldarg_0);
                ilGenerator.Emit(OpCodes.Ldftn, m_CallBackMethods[i]);
                ilGenerator.Emit(OpCodes.Newobj, m_NestedTypeConstructors[i]);
                ilGenerator.Emit(OpCodes.Stfld, m_MultiCastDelegates[i]);
            }
            ilGenerator.Emit(OpCodes.Ret);

        }

        /// <summary>
        /// Wraps the specified type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        public Object Wrap(Type type)
        {
            Type newType = null;
            try
            {
                m_Type = type;
                GenerateType();
                GenerateDelegateClass();
                GenerateFields();
                GenerateCallBackMethods();
                GenerateOverrideMethods();
                GenerateConstructor();
                newType = m_TypeBuilder.CreateType();  //建立代理类的Type
                //建立Nested Class的Type
                foreach (TypeBuilder tb in m_NestedTypeBuilders)
                    tb.CreateType();
                m_Assembly.Save("Func.dll");//保存这个代理类为Func.dll
            }
            catch (Exception err)
            {
                throw err;
            }
            //建立代理类实例
            return Activator.CreateInstance(newType, new Interceptor());
        }

        static void Main(string[] args)
        {
            Program dynamicProxyBuilder = new Program();
            Class1 class1 = (Class1)dynamicProxyBuilder.Wrap(typeof(Class1));
            class1.MyMethod();
            Console.Read();
        }
    }
}

下面是ILSAM的一个解图:[IL里面大变样]

Advertisements