前面的文章中,我犯了一个错误,导致在生成的实例无法被调试,这次修正了,代码如下:

    #region Delegates

    public delegate object InvocationDelegate(object target
        , System.Reflection.MethodBase method
        , object[] parameters);

    #endregion Delegates

    public interface IDynamicProxy
    {
        #region Properties

        InvocationDelegate InvocationHandler
        {
            get;
            set;
        }

        object ProxyTarget
        {
            get;
            set;
        }

        bool Strict
        {
            get;
            set;
        }

        Type[] SupportedTypes
        {
            get;
            set;
        }

        #endregion Properties
    }

    public class DynamicProxyFactory
    {
        #region Fields

        private static string Interface_DefaultNameSpace = "L.D.P.A.C";
        private static Dictionary<string, Type> Interface_HashTypes = new Dictionary<string, Type>();

        #endregion Fields

        #region Constructors

        private DynamicProxyFactory()
        {
        }

        #endregion Constructors

        #region Methods

        public static INTERFACE CreateImplement<INTERFACE>(object instance)
            where INTERFACE : class
        {
            return CreateImplement(typeof(INTERFACE), instance) as INTERFACE;
        }

        public static object CreateImplement(Type interfaceType, object inpmlementInstance)
        {
            if (null == interfaceType)
            {
                throw new ArgumentException("The first parameter must not be null!");
            }
            if (null == inpmlementInstance)
            {
                return CreateImplement(interfaceType);
            }
            else
            {
                Type type = GenerateInterfaceImplementType(interfaceType, inpmlementInstance.GetType());
                return Activator.CreateInstance(type, inpmlementInstance);
            }
        }

        public static object CreateImplement(Type interfaceType)
        {
            if (null == interfaceType)
            {
                throw new ArgumentException("The first parameter must not be null!");
            }
            if (interfaceType.IsInterface)
            {
                Type type = GenerateInterfaceImplementType(interfaceType, null);
                return Activator.CreateInstance(type);
            }
            else
            {
                //Guess interface
                Type[] ints = interfaceType.GetInterfaces();
                if (null == ints)
                {
                    throw new ArgumentException(interfaceType.FullName + ": could not found the interface it derived.");
                }
                if (ints.Length > 1)
                {
                    throw new ArgumentException(interfaceType.FullName + ": More than one interfaces it derived.");
                }
                //create a new instance of the target class
                object instance = Activator.CreateInstance(interfaceType);
                Type type = GenerateInterfaceImplementType(interfaceType, ints[0]);
                return Activator.CreateInstance(type, instance);
            }
        }

        public static INTERFACE CreateImplement<INTERFACE>()
            where INTERFACE : class
        {
            return CreateImplement(typeof(INTERFACE)) as INTERFACE;
        }

        public static object CreateProxy(Type target, InvocationDelegate invocationHandler)
        {
            return CreateProxy(CreateImplement(target), invocationHandler);
        }

        public static object CreateProxy(object target, InvocationDelegate invocationHandler)
        {
            return CreateProxy(target, invocationHandler, false, null);
        }

        public static object CreateProxy(Type target, InvocationDelegate invocationHandler, bool strict)
        {
            return CreateProxy(CreateImplement(target), invocationHandler, strict);
        }

        public static object CreateProxy(object target, InvocationDelegate invocationHandler, bool strict)
        {
            return CreateProxy(target, invocationHandler, strict, null);
        }

        public static object CreateProxy(Type target, InvocationDelegate invocationHandler, bool strict, Type[] supportedTypes)
        {
            return CreateProxy(CreateImplement(target), invocationHandler, strict, supportedTypes);
        }

        public static object CreateProxy(object target, InvocationDelegate invocationHandler, bool strict, Type[] supportedTypes)
        {
            return new DynamicProxyImpl(target, invocationHandler, strict, supportedTypes).GetTransparentProxy();
        }
        public static Type GenerateInterfaceImplementType(Type typeInterface, Type typeImplement)
        {
            if (null == typeInterface)
            {
                throw new ArgumentException("The first argument must not be null!");
            }
            if (typeInterface.IsInterface==false)
            {
                throw new ArgumentException(typeInterface.FullName + " must be an interface instead of a class");
            }
            string strTypeName = Interface_DefaultNameSpace+"." + typeInterface.ToString() + "_" + (typeImplement == null ? "Impl" : typeImplement.ToString());
            if (Interface_HashTypes.ContainsKey(strTypeName))
            {
                return Interface_HashTypes[strTypeName];
            }
            System.Diagnostics.Debug.WriteLine("Create a new implements for >>>>>>>>" + typeInterface.FullName);
            lock (Interface_HashTypes)
            {
                List<PropertyInfo> pisInterface = TypeHelper.GetAllPropertyInfos(typeInterface);
                List<MethodInfo> misInterfaceList = TypeHelper.GetAllMethodInfos(typeInterface,false);
                List<MethodInfo> misImplex = typeImplement == null ? null : TypeHelper.GetAllMethodInfos(typeImplement,true, BindingFlags.Public | BindingFlags.Instance);
                AssemblyName aName = new AssemblyName(Interface_DefaultNameSpace);
                AssemblyBuilder assemblyBuilder =
                    AppDomain.CurrentDomain.DefineDynamicAssembly(
                        aName,
                        AssemblyBuilderAccess.RunAndSave);
                ModuleBuilder moduleBuilder =
                    assemblyBuilder.DefineDynamicModule(aName.Name, aName.Name + ".dll",true);

                TypeBuilder typeBuilder = moduleBuilder.DefineType(strTypeName,
                    TypeAttributes.Public, null, new Type[] { typeInterface });
                FieldBuilder innerParentObject =
                    null == typeImplement ?null:
                    typeBuilder.DefineField(
                    "internal__wrappedInstance",typeImplement,
                    FieldAttributes.Private);

                ConstructorBuilder ctor1 = typeBuilder.DefineConstructor(
                    MethodAttributes.Public,
                    CallingConventions.Standard,
                    null == typeImplement ? Type.EmptyTypes : new Type[] { typeImplement });
                ILGenerator constructorIL = ctor1.GetILGenerator();
                if (null != typeImplement)
                {
                    //父亲构造
                    constructorIL.Emit(OpCodes.Ldarg_0);
                    constructorIL.Emit(OpCodes.Call, typeImplement.GetConstructor(Type.EmptyTypes));
                    //设置私有变量值
                    constructorIL.Emit(OpCodes.Ldarg_0);
                    constructorIL.Emit(OpCodes.Ldarg_1);
                    constructorIL.Emit(OpCodes.Stfld, innerParentObject);
                    constructorIL.Emit(OpCodes.Ret);
                }
                else
                {
                    constructorIL.Emit(OpCodes.Ret);
                }
                foreach (PropertyInfo item in pisInterface)
                {
                    MethodInfo getMi = _FindGetMethodInfo(misImplex, item);
                    MethodInfo setMi = _FindSetMethodInfo(misImplex, item);
                    _CreateProperty(typeBuilder, innerParentObject, item, getMi, setMi);
                }

                foreach (MethodInfo item in misInterfaceList)
                {
                    MethodInfo instanceMi = _FindMethodInfo(misImplex, item);
                    _CreateMethod(typeBuilder, innerParentObject, item, instanceMi);
                }
                Type newType = typeBuilder.CreateType();
                Interface_HashTypes.Add(strTypeName, newType);
                return newType;
            }
        }

        private static MethodInfo _FindSetMethodInfo(List<MethodInfo> miList, PropertyInfo pi)
        {
            if (null == miList || null == pi)
            {
                return null;
            }
            foreach (MethodInfo item in miList)
            {
                if (item.Name.Equals("set_" + pi.Name) && item.IsSpecialName)
                {
                    return item;
                }
            }

            return null;
        }

        private static Type GenerateInterfaceImplementType(Type typeInterface)
        {
            return GenerateInterfaceImplementType(typeInterface, null);
        }

        private static void _CreateMethod(TypeBuilder typeBuilder, FieldBuilder innerParentObject
            , MethodInfo mi, MethodInfo instanceMi)
        {
            List<Type> paramTyleList = new List<Type>();
            foreach (var item in mi.GetParameters())
                paramTyleList.Add(item.ParameterType);

            MethodBuilder mb = typeBuilder.DefineMethod(
              mi.Name,
              MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final,
              mi.ReturnType,
              paramTyleList.ToArray());

            ILGenerator il = mb.GetILGenerator();
            if (instanceMi == null)
            {
                il.Emit(OpCodes.Newobj, typeof(NotImplementedException).GetConstructor(new Type[] { }));
                il.Emit(OpCodes.Throw);
            }
            else
            {
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, innerParentObject);
                switch (paramTyleList.Count)
                {
                    case 0:
                        break;
                    case 1:
                        il.Emit(OpCodes.Ldarg_1);
                        break;
                    case 2:
                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Ldarg_2);
                        break;
                    case 3:
                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Ldarg_2);
                        il.Emit(OpCodes.Ldarg_3);
                        break;
                    default:
                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Ldarg_2);
                        il.Emit(OpCodes.Ldarg_3);

                        Int32 sCount = Math.Min(paramTyleList.Count, 127);
                        for (int i = 4; i <= sCount; i++)
                        {
                            il.Emit(OpCodes.Ldarg_S, i);
                        }

                        for (int i = 128; i <= paramTyleList.Count; i++)
                        {
                            il.Emit(OpCodes.Ldarg, i);
                        }

                        break;
                }
                //Invoke the old functionality
                il.Emit(OpCodes.Callvirt, instanceMi);
                il.Emit(OpCodes.Ret);
            }
        }

        private static void _CreateProperty(TypeBuilder typeBuilder, FieldBuilder innerParentObject
            , PropertyInfo pi, MethodInfo getMi, MethodInfo setMi)
        {
            FieldBuilder privateField = null;
            if (null == getMi || null == setMi)
            {
                privateField = typeBuilder.DefineField("private_____" + pi.Name, pi.PropertyType, FieldAttributes.Private);
            }
            String name = pi.Name;
            Type type = pi.PropertyType;

            PropertyBuilder pb = typeBuilder.DefineProperty(
                name,
                PropertyAttributes.HasDefault,
                type,
                null);

            MethodAttributes getSetAttr = MethodAttributes.Public
                | MethodAttributes.SpecialName
                | MethodAttributes.HideBySig
                | MethodAttributes.NewSlot
                | MethodAttributes.Virtual
                | MethodAttributes.Final;
            MethodBuilder mbGetAccessor = typeBuilder.DefineMethod(
                "get_" + name,
                getSetAttr,
                type,
                Type.EmptyTypes);
            {
                ILGenerator getIL = mbGetAccessor.GetILGenerator();
                if (getMi != null)
                {
                    getIL.Emit(OpCodes.Ldarg_0);
                    getIL.Emit(OpCodes.Ldfld, innerParentObject);
                    getIL.Emit(OpCodes.Callvirt, getMi);
                    getIL.Emit(OpCodes.Ret);
                }
                else
                {
                    getIL.Emit(OpCodes.Ldarg_0);
                    getIL.Emit(OpCodes.Ldfld, privateField);
                    getIL.Emit(OpCodes.Ret);
                }
            }
            MethodBuilder mbSetAccessor = typeBuilder.DefineMethod(
                "set_" + name,
                getSetAttr,
                null,
                new Type[] { type });
            {
                ILGenerator setIL = mbSetAccessor.GetILGenerator();
                if (setMi != null)
                {
                    setIL.Emit(OpCodes.Ldarg_0);
                    setIL.Emit(OpCodes.Ldfld, innerParentObject);
                    setIL.Emit(OpCodes.Ldarg_1);
                    setIL.Emit(OpCodes.Callvirt, setMi);
                    setIL.Emit(OpCodes.Ret);
                }
                else
                {
                    setIL.Emit(OpCodes.Ldarg_0);
                    setIL.Emit(OpCodes.Ldarg_1);
                    setIL.Emit(OpCodes.Stfld, privateField);
                    setIL.Emit(OpCodes.Ret);
                }
            }
            if (pi.CanRead)
            {
                pb.SetGetMethod(mbGetAccessor);
            }
            if (pi.CanWrite)
            {
                pb.SetSetMethod(mbSetAccessor);
            }
        }

        private static MethodInfo _FindGetMethodInfo(List<MethodInfo> miList, PropertyInfo pi)
        {
            if (null == miList || null == pi)
            {
                return null;
            }
            foreach (MethodInfo item in miList)
            {
                if (item.Name.Equals("get_" + pi.Name) && item.IsSpecialName)
                {
                    return item;
                }
            }
            return null;
        }

        private static MethodInfo _FindMethodInfo(List<MethodInfo> miList, MethodInfo mi)
        {
            if (null == miList || null == mi)
            {
                return null;
            }
            foreach (var item in miList)
            {
                if (_MethodInfoEqual(item, mi)) return item;
            }

            return null;
        }

        private static Boolean _MethodInfoEqual(MethodInfo mi1, MethodInfo mi2)
        {
            if (mi1.IsSpecialName == true || mi2.IsSpecialName == true) return false;
            if (mi1.Name != mi2.Name) return false;
            if (mi1.ReturnType != mi2.ReturnType) return false;
            ParameterInfo[] pis1 = mi1.GetParameters();
            ParameterInfo[] pis2 = mi2.GetParameters();
            if (pis1.Length != pis2.Length) return false;
            for (int i = 0; i < pis1.Length; i++)
            {
                ParameterInfo pi1 = pis1[i];
                ParameterInfo pi2 = pis2[i];
                if (pi1.ParameterType != pi2.ParameterType) return false;
            }
            return true;
        }

        #endregion Methods
    }

    public class DynamicProxyImpl :
        System.Runtime.Remoting.Proxies.RealProxy
        , IDynamicProxy
        , System.Runtime.Remoting.IRemotingTypeInfo
    {
        #region Fields

        private InvocationDelegate invocationHandler;
        private object proxyTarget;
        private bool strict;
        private Type[] supportedTypes;

        #endregion Fields

        #region Constructors

        protected internal DynamicProxyImpl(object proxyTarget
            , InvocationDelegate invocationHandler
            , bool strict
            , Type[] supportedTypes)
            : base(typeof(IDynamicProxy))
        {
            this.proxyTarget = proxyTarget;
            this.invocationHandler = invocationHandler;
            this.strict = strict;
            this.supportedTypes = supportedTypes;
        }

        #endregion Constructors

        #region Properties

        public InvocationDelegate InvocationHandler
        {
            get { return invocationHandler; }
            set { invocationHandler = value; }
        }

        public object ProxyTarget
        {
            get { return proxyTarget; }
            set { proxyTarget = value; }
        }

        public bool Strict
        {
            get { return strict; }
            set { strict = value; }
        }

        public Type[] SupportedTypes
        {
            get { return supportedTypes; }
            set { supportedTypes = value; }
        }

        public string TypeName
        {
            get { throw new System.NotSupportedException("TypeName for DynamicProxy isn't supported"); }
            set { throw new System.NotSupportedException("TypeName for DynamicProxy isn't supported"); }
        }

        #endregion Properties

        #region Methods

        public bool CanCastTo(System.Type toType, object obj)
        {
            // Assume we can (which is the default unless strict is true)
            bool canCast = true;

            if (strict)
            {
                // First check if the proxyTarget supports the cast
                if (toType.IsAssignableFrom(proxyTarget.GetType()))
                {
                    canCast = true;
                }
                else if (supportedTypes != null)
                {
                    canCast = false;
                    // Check if the list of supported interfaces supports the cast
                    foreach (Type type in supportedTypes)
                    {
                        if (toType == type)
                        {
                            canCast = true;
                            break;
                        }
                    }
                }
                else
                {
                    canCast = false;
                }
            }

            return canCast;
        }

        public override System.Runtime.Remoting.ObjRef CreateObjRef(System.Type type)
        {
            throw new NotSupportedException("ObjRef for DynamicProxy isn't supported");
        }

        public override System.Runtime.Remoting.Messaging.IMessage Invoke(System.Runtime.Remoting.Messaging.IMessage message)
        {
            // Convert to a MethodCallMessage
            System.Runtime.Remoting.Messaging.IMethodCallMessage methodMessage = new System.Runtime.Remoting.Messaging.MethodCallMessageWrapper((System.Runtime.Remoting.Messaging.IMethodCallMessage)message);

            // Extract the method being called
            System.Reflection.MethodBase method = methodMessage.MethodBase;

            // Perform the call
            object returnValue = null;
            if (method.DeclaringType == typeof(IDynamicProxy))
            {
                // Handle IDynamicProxy interface calls on this instance instead of on the proxy target instance
                returnValue = method.Invoke(this, methodMessage.Args);
            }
            else
            {
                // Delegate to the invocation handler
                returnValue = invocationHandler(proxyTarget, method, methodMessage.Args);
            }

            // Create the return message (ReturnMessage)
            System.Runtime.Remoting.Messaging.ReturnMessage returnMessage = new System.Runtime.Remoting.Messaging.ReturnMessage(returnValue, methodMessage.Args, methodMessage.ArgCount, methodMessage.LogicalCallContext, methodMessage);
            return returnMessage;
        }

        #endregion Methods
    }


Jeason Zhao (沈胜衣,斛律光) ------雪饮再现,一个人的江湖
我知道我是谁,我是沈胜衣,默默的活着,就像空气。