.net的动态代理

来源:互联网 发布:mac带圈圈的数字怎么打 编辑:程序博客网 时间:2024/05/16 17:22
动态代理 DynamicProxy,这里说的动态代理是直接使用Castle.net 中提供的,并非自己实现的,在项目早期自己尝试过创建一个自己的动态代理类,虽然能够实现,但是功能上还是太弱了一些,如果追加功能就变得和Castle.net 的一样了,所以就直接采用人家的了。。。

=============咯咯咯=============

动态代理的工作模式:

一般我们获取一个类型的实例都是通过 new 关键字,例如 var c = new Class1(); 通过动态代理的话,我们获取一个实例是通过代理方法获取的,generator.CreateClassProxy(type, interceptor); 其中Type是要代理的类型,也就是Class1(); interceptor则是实际执行代理的拦截器。

为什么我们要这么麻烦的使用代理而不是直接new实例?

简单的说,例如我Class1与Class2都有自己的方法,我现在想给这两给类的每个方法都添加一个日志操作,如果不通过代理我们怎么做呢?每个函数开始增加一句Log.Enter();结束的时候增加一个Log.Exit(); 如果涉及到TryCatch这类的,会更麻烦。通过动态代理,我们可以增加一个拦截器,拦截器中,可以先执行Log.Enter();然后执行实际操作,最后在执行Log.Exit();  这样我们就不需要去修改 Class1与Class2两个类。


在这个项目里,动态代理有两个功能,一个是将客户端与服务端分离,另一个是提供日志代理。日志代理上面已经说了,现在说怎么实现客户端与服务端的分离。

在客户端调用服务端的服务时,我们一般会采用WCF,WebService之类的服务提供者,但是我们的项目比较特殊,他的客户可能会要求使用客户端与服务端分离,也有可能要求他们一起部署,及最简单的所有的东西都在一起,看上去是一个大个的客户端。

所以在开发的时候,要求客户端程序员,不能直接new出任何服务,所有的服务必须通过GetService获取,这样,根据客户的要求来实现分离或者整合,因为所有的操作都是在动态代理中执行的,所以只需要将动态代理的代理结果交给Communication组件既可以完成。

=========Communication===========

Communication组件是基本组件之一,负责执行动态代理传递过来的结果,其接口有两个方法:

[csharp] view plaincopy
  1. /// <summary>  
  2. /// 执行操作  
  3. /// </summary>  
  4. /// <param name="method">函数信息</param>  
  5. /// <param name="parameter">调用参数</param>  
  6. object Execute(String method, Object parameter);  
  7.   
  8. /// <summary>  
  9. /// 获取或设置异步接口调用的中转委托信息  
  10. /// </summary>  
  11. void AsycExecute(String method, Object parameter, Delegate Continue);  

通过这两个方法的具体执行内容的变换,就可以替换为不同的服务端操作了。

==============DynamicProxy=======================

部分动态代理的代码:

拦截器(ServiceInterceptor):

[csharp] view plaincopy
  1. /// <summary>  
  2. /// 服务拦截器  
  3. /// </summary>  
  4. public class ServiceInterceptor : IInterceptor  
  5. {  
  6.     /// <summary>  
  7.     /// 获取或设置函数操作之前要执行的委托  
  8.     /// </summary>  
  9.     public Action<Object> BeforeMethod { getset; }  
  10.     /// <summary>  
  11.     /// 函数操作之后要执行的委托  
  12.     /// </summary>  
  13.     public Action<Object> AfterMethod { getset; }  
  14.     /// <summary>  
  15.     /// 函数操作之前要执行的委托的参数  
  16.     /// </summary>  
  17.     public Object BeforeMethodParameter { getset; }  
  18.     /// <summary>  
  19.     /// 函数操作之后要执行的委托的参数  
  20.     /// </summary>  
  21.     public Object AfterMethodParameter { getset; }  
  22.     /// <summary>  
  23.     /// 获取或设置接口调用的中转委托信息  
  24.     /// </summary>  
  25.     public Func<String, Object, Object> InterfaceInvoke { getset; }  
  26.   
  27.     /// <summary>  
  28.     /// 获取或设置异步接口调用的中转委托信息  
  29.     /// </summary>  
  30.     public Action<String, Object, Delegate> AsycInterfaceInvoke { getset; }  
  31.   
  32.     /// <summary>  
  33.     /// 异步后续处理函数  
  34.     /// </summary>  
  35.     public Delegate Continue { getset; }  
  36.   
  37.     /// <summary>  
  38.     /// 获取或设置是否为接口  
  39.     /// </summary>  
  40.     public bool IsInterface { getset; }  
  41.   
  42.     /// <summary>  
  43.     /// 拦截  
  44.     /// </summary>  
  45.     public void Intercept(IInvocation invocation)  
  46.     {  
  47.         // 前操作不为空,执行  
  48.         if (BeforeMethod != null)  
  49.         {  
  50.             BeforeMethod(BeforeMethodParameter);  
  51.         }  
  52.   
  53.         if (IsInterface)  
  54.         {  
  55.             // 接口  
  56.             if ((InterfaceInvoke != null || AsycInterfaceInvoke != null)  
  57.                 && invocation.Method.DeclaringType != null)  
  58.             {  
  59.                 // 接口委托不为空,接口定义类型不为空  
  60.                 if (Continue == null)  
  61.                 {  
  62.                     // 执行接口委托,并设置返回值  
  63.                     invocation.ReturnValue = InterfaceInvoke(String.Format("{0}.{1}", invocation.Method.DeclaringType.FullName, invocation.Method.Name), invocation.Arguments);  
  64.                 }  
  65.                 else  
  66.                 {  
  67.                     // 执行异步操作  
  68.                     AsycInterfaceInvoke(String.Format("{0}.{1}", invocation.Method.DeclaringType.FullName, invocation.Method.Name), invocation.Arguments, Continue);  
  69.                 }  
  70.             }  
  71.         }  
  72.         else  
  73.         {  
  74.             invocation.Proceed();  
  75.         }  
  76.   
  77.         // 后操作不为空,执行  
  78.         if (AfterMethod != null)  
  79.         {  
  80.             AfterMethod(AfterMethodParameter);  
  81.         }  
  82.     }  
  83. }  


DynamicProxy 类:
[csharp] view plaincopy
  1. /// <summary>  
  2. /// 动态代理  
  3. /// </summary>  
  4. public static class DynamicProxy  
  5. {  
  6.     /// <summary>  
  7.     /// 获取或设置日志  
  8.     /// </summary>  
  9.     public static ILog Logger { getset; }  
  10.   
  11.     /// <summary>  
  12.     /// 获取或设置接口调用的中转委托信息  
  13.     /// </summary>  
  14.     public static Func<String, Object, Object> InterfaceInvoke { getset; }  
  15.   
  16.     /// <summary>  
  17.     /// 获取或设置异步接口调用的中转委托信息  
  18.     /// </summary>  
  19.     public static Action<String, Object, Delegate> AsycInterfaceInvoke { getset; }  
  20.   
  21.     /// <summary>  
  22.     /// 获取含有代理的实例  
  23.     /// </summary>  
  24.     /// <param name="typeName">实例类型</param>  
  25.     /// <param name="beforeMethod">函数操作之前要执行的委托</param>  
  26.     /// <param name="afterMethod">函数操作之后要执行的委托</param>  
  27.     /// <param name="beforeMethodParameter">函数操作之前要执行的委托的参数</param>  
  28.     /// <param name="afterMethodParameter">函数操作之后要执行的委托的参数</param>  
  29.     /// <returns>含有代理类的实例</returns>  
  30.     public static Object GetInstance(String typeName, Action<Object> beforeMethod, Action<Object> afterMethod,  
  31.                                    Object beforeMethodParameter = null, Object afterMethodParameter = null)  
  32.     {  
  33.         var assemblies = AppDomain.CurrentDomain.GetAssemblies();  
  34.   
  35.         Type type = null;  
  36.         foreach (var assembly in assemblies)  
  37.         {  
  38.             type = assembly.GetType(typeName);  
  39.             if (type != nullbreak;  
  40.         }  
  41.   
  42.         return CreateInstance(beforeMethod, afterMethod, beforeMethodParameter, afterMethodParameter, type);  
  43.   
  44.     }  
  45.   
  46.     /// <summary>  
  47.     /// 获取含有代理的实例  
  48.     /// </summary>  
  49.     /// <param name="beforeMethod">函数操作之前要执行的委托</param>  
  50.     /// <param name="afterMethod">函数操作之后要执行的委托</param>  
  51.     /// <param name="beforeMethodParameter">函数操作之前要执行的委托的参数</param>  
  52.     /// <param name="afterMethodParameter">函数操作之后要执行的委托的参数</param>  
  53.     /// <param name="type">实例类型</param>  
  54.     /// <returns>含有代理类的实例</returns>  
  55.     private static object CreateInstance(Action<object> beforeMethod, Action<object> afterMethod,  
  56.                                          object beforeMethodParameter, object afterMethodParameter, Type type)  
  57.     {  
  58.         if (type == nullreturn null;  
  59.   
  60.         ProxyGenerator generator = new ProxyGenerator();  
  61.         var interceptor = new ServiceInterceptor  
  62.         {  
  63.             AfterMethod = afterMethod,  
  64.             AfterMethodParameter = afterMethodParameter,  
  65.             BeforeMethod = beforeMethod,  
  66.             BeforeMethodParameter = beforeMethodParameter,  
  67.             InterfaceInvoke = InterfaceInvoke,  
  68.             IsInterface = type.IsInterface,  
  69.             AsycInterfaceInvoke = AsycInterfaceInvoke  
  70.         };  
  71.   
  72.         if (type.IsInterface)  
  73.         {  
  74.             return generator.CreateInterfaceProxyWithoutTarget(type, interceptor);  
  75.         }  
  76.   
  77.         return generator.CreateClassProxy(type, interceptor);  
  78.     }  
  79.   
  80.     /// <summary>  
  81.     /// 获取含有代理的实例  
  82.     /// </summary>  
  83.     /// <typeparam name="T">实例类型</typeparam>  
  84.     /// <param name="beforeMethod">函数操作之前要执行的委托</param>  
  85.     /// <param name="afterMethod">函数操作之后要执行的委托</param>  
  86.     /// <param name="beforeMethodParameter">函数操作之前要执行的委托的参数</param>  
  87.     /// <param name="afterMethodParameter">函数操作之后要执行的委托的参数</param>  
  88.     /// <returns>含有代理类的实例</returns>  
  89.     public static T GetInstance<T>(Action<Object> beforeMethod, Action<Object> afterMethod,  
  90.                                    Object beforeMethodParameter = null, Object afterMethodParameter = null)  
  91.     {  
  92.         Type type = typeof(T);  
  93.         return (T)CreateInstance(beforeMethod, afterMethod, beforeMethodParameter, afterMethodParameter, type);  
  94.     }  
  95.   
  96.     /// <summary>  
  97.     /// 获取日志实例  
  98.     /// </summary>  
  99.     /// <typeparam name="T">实例类型</typeparam>  
  100.     /// <returns>包含有日志的代理实例</returns>  
  101.     public static T GetLogInstance<T>()  
  102.     {  
  103.         return GetInstance<T>(Logger.CallLog, Logger.CallLog);  
  104.     }  

MethodCommunication类,该类中直接执行委托的方法,不区分客户端与服务端:
[csharp] view plaincopy
  1. /// <summary>  
  2. /// 客户端服务通信方法类  
  3. /// </summary>  
  4. public class MethodCommunication : PluginBase, ICommunication  
  5. {  
  6.     #region ICommunication Members  
  7.   
  8.     /// <summary>  
  9.     /// 获取许可密钥  
  10.     /// </summary>  
  11.     /// <summary>  
  12.     /// 获取许可密钥  
  13.     /// </summary>  
  14.     public override string LicenseKey  
  15.     {  
  16.         get { return ""; }  
  17.     }  
  18.   
  19.     /// <summary>  
  20.     /// 执行操作  
  21.     /// </summary>  
  22.     /// <param name="method">函数信息</param>  
  23.     /// <param name="parameter">调用参数</param>  
  24.     public object Execute(String method, Object parameter)  
  25.     {  
  26.         if (Executing != null) Executing(thisnew EventArgs());  
  27.         OnExecuting();  
  28.   
  29.         // 获取类型名称  
  30.         string[] classPart = method.Split('.');  
  31.         var classBuilder = new StringBuilder();  
  32.         for (int i = 0; i < classPart.Length - 1; i++)  
  33.         {  
  34.             classBuilder.Append(classPart[i]);  
  35.             classBuilder.Append('.');  
  36.         }  
  37.   
  38.         classBuilder.Remove(classBuilder.Length - 1, 1);  
  39.         // 获取服务   
  40.         object service = GetInstance(classBuilder.ToString());  
  41.         if (service == nullthrow new VerificationException("Didn't find the service at MethodCommunication.");  
  42.   
  43.         // 获取函数信息  
  44.         Type serviceType = service.GetType();  
  45.         MethodInfo methodInfo = serviceType.GetMethod(classPart[classPart.Length - 1]);  
  46.   
  47.         var temp = parameter as IEnumerable;  
  48.         IList<object> parameters = temp == null ? new List<object> { parameter } : temp.Cast<object>().ToList();  
  49.   
  50.         // 执行  
  51.         object reslut = methodInfo.Invoke(service, parameters.ToArray());  
  52.   
  53.         OnExcuted();  
  54.         if (Excuted != null) Excuted(thisnew EventArgs());  
  55.   
  56.         return reslut;  
  57.     }  
  58.   
  59.     /// <summary>  
  60.     /// 获取或设置异步接口调用的中转委托信息  
  61.     /// </summary>  
  62.     public void AsycExecute(String method, Object parameter, Delegate Continue)  
  63.     {  
  64.         if (Continue.Method.GetParameters().Length == 0)  
  65.         {  
  66.             var task = new Task(() => Execute(method, parameter));  
  67.             task.ContinueWith(tr => Continue.DynamicInvoke());  
  68.             task.Start();  
  69.         }  
  70.         else  
  71.         {  
  72.             var task = new Task<Object>(() => Execute(method, parameter));  
  73.             task.ContinueWith(tr => Continue.DynamicInvoke(tr.Result));  
  74.             task.Start();  
  75.         }  
  76.     }  
  77.   
  78.     /// <summary>  
  79.     /// 操作开始执行  
  80.     /// </summary>  
  81.     public virtual void OnExecuting()  
  82.     {  
  83.     }  
  84.   
  85.     /// <summary>  
  86.     /// 操作执行结束  
  87.     /// </summary>  
  88.     public virtual void OnExcuted()  
  89.     {  
  90.     }  
  91.   
  92.     /// <summary>  
  93.     /// 操作执行结束事件  
  94.     /// </summary>  
  95.     public event EventHandler Excuted;  
  96.   
  97.     /// <summary>  
  98.     /// 操作执行开始事件  
  99.     /// </summary>  
  100.     public event EventHandler Executing;  
  101.  
  102.     #endregion  
  103.   
  104.     /// <summary>  
  105.     /// 获取实例  
  106.     /// </summary>  
  107.     /// <param name="typeFullName">类型名称</param>  
  108.     /// <returns>获取的实例</returns>  
  109.     protected virtual Object GetInstance(String typeFullName)  
  110.     {  
  111.         return App.GetService(typeFullName);  
  112.     }  

WCF与其他的 ICommunication类这里就不给出了,基本上都是差不多的。
原创粉丝点击