C#Emit动态代理类更新.doc_第1页
C#Emit动态代理类更新.doc_第2页
C#Emit动态代理类更新.doc_第3页
C#Emit动态代理类更新.doc_第4页
C#Emit动态代理类更新.doc_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

在前面的文章中,我犯了一个错误,导致在生成的实例无法被调试,这次修正了,代码如下: #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 Interface_HashTypes = new Dictionary(); #endregion Fields #region Constructors private DynamicProxyFactory() #endregion Constructors #region Methods public static INTERFACE CreateImplement(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, ints0); return Activator.CreateInstance(type, instance); public static INTERFACE CreateImplement() 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_HashTypesstrTypeName; System.Diagnostics.Debug.WriteLine(Create a new implements for + typeInterface.FullName); lock (Interface_HashTypes) List pisInterface = TypeHelper.GetAllPropertyInfos(typeInterface); List misInterfaceList = TypeHelper.GetAllMethodInfos(typeInterface,false); List 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 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 paramTyleList = new List(); 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 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 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 = pis1i; ParameterInfo pi2 = pis2i; 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) xyTarget = 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

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论