zoukankan      html  css  js  c++  java
  • 使用Unity2.0的Interceptor实现简单AOP

            Unity 2.0 现在已经是Enterprise Library 中一个模块了。我们可以使用Unity 2.0的Interceptor来拦截方法最终实现AOP。它的实现是这样的,看下面的图比较清楚:

    unity

            让我们看下面的DEMO代码:

       1:      public interface IDAL
       2:      {
       3:          void MethodForLoggingA();
       4:          void MethodForLoggingB();
       5:          void MethodForLoggingC(int num);
       6:      }

           实现类:

       1:      public class DAL : IDAL
       2:      {
       3:          public virtual void MethodForLoggingA()
       4:          {
       5:              Console.WriteLine("Called MethodForLoggingA");
       6:          }
       7:          public virtual void MethodForLoggingB()
       8:          {
       9:              Console.WriteLine("Called MethodForLoggingB");
      10:          }
      11:          public virtual  void MethodForLoggingC(int num)
      12:          {
      13:              Console.WriteLine("Called MethodForLoggingC {0}", num);
      14:          }
      15:      }

           让我们来写一个自定义拦截行为,我们需要继承自这个IInterceptionBehavior,假设我们要记录方法调用的全过程。

       1:      public class MyInterceptor : IInterceptionBehavior
       2:      {
       3:          public IEnumerable<Type> GetRequiredInterfaces()
       4:          {
       5:              return Type.EmptyTypes;
       6:          }
       7:   
       8:          public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
       9:          {
      10:              /* Call the method that was intercepted */
      11:              string className = input.MethodBase.DeclaringType.Name;
      12:              string methodName = input.MethodBase.Name;
      13:              string generic = input.MethodBase.DeclaringType.IsGenericType ? string.Format("<{0}>", input.MethodBase.DeclaringType.GetGenericArguments().ToStringList()) : string.Empty;
      14:              string arguments = input.Arguments.ToStringList();
      15:   
      16:              string preMethodMessage = string.Format("{0}{1}.{2}({3})", className, generic, methodName, arguments);
      17:              Console.WriteLine("PreMethodCalling: " + preMethodMessage);
      18:              //Logging
      19:              Logger.Instance.Log(preMethodMessage);
      20:              //Invoke method
      21:              IMethodReturn msg = getNext()(input, getNext);
      22:              //Post method calling
      23:              string postMethodMessage = string.Format("{0}{1}.{2}() -> {3}", className, generic, methodName, msg.ReturnValue);
      24:              Console.WriteLine("PostMethodCalling: " + postMethodMessage);
      25:              //Logging
      26:              Logger.Instance.Log(postMethodMessage);
      27:              return msg;
      28:          }
      29:   
      30:          public bool WillExecute
      31:          {
      32:              get { return true; }
      33:          }
      34:      }
      35:   
      36:      public class Logger
      37:      {
      38:          private static Logger _instance = new Logger();
      39:          public static Logger Instance { get { return _instance; } }
      40:          public void Log(string message)
      41:          {
      42:              //logging code
      43:          }
      44:      }
      45:   
      46:      public static class EnumerableExtensions
      47:      {
      48:          public static string ToStringList(this IEnumerable list)
      49:          {
      50:              StringBuilder sb = new StringBuilder();
      51:   
      52:              foreach (var item in list)
      53:              {
      54:                  sb.AppendFormat("{0}, ", item);
      55:              }
      56:              if (sb.Length > 0)
      57:                  sb.Remove(sb.Length - 2, 2);
      58:   
      59:              return sb.ToString();
      60:          }
      61:      }

    客户端的代码是这样的:

       1:          static void Main(string[] args)
       2:          {
       3:              IUnityContainer container = new UnityContainer();
       4:              container.AddNewExtension<Interception>();
       5:              container.RegisterType<IDAL, DAL>(
       6:              //only block virtual method
       7:              new Interceptor<VirtualMethodInterceptor>(),
       8:                //new Interceptor<InterfaceInterceptor>(),
       9:                //new Interceptor<TransparentProxyInterceptor>(),
      10:              new InterceptionBehavior<MyInterceptor>()   
      11:              );
      12:   
      13:              var dal = container.Resolve<IDAL>();
      14:   
      15:              dal.MethodForLoggingA();
      16:   
      17:              dal.MethodForLoggingB();
      18:   
      19:              dal.MethodForLoggingC(8);
      20:   
      21:              Console.Read();
      22:   
      23:          }

       对于上面这个DEMO,Unity提供的三个拦截器我们都可以使用。但注意 VirtualMethodInterceptor 只能对虚方法拦截。它们之间优缺点看下表(msdn):

    Type

    Advantages

    Disadvantages

    Transparent Proxy Interceptor

    Can intercept all methods of the target object (virtual, non-virtual, or interface).

    The object must either implement an interface or inherit from System.MarshalByRefObject. If the marshal by reference object is not a base class, you can only proxy interface methods. The Transparent Proxy process is much slower than a regular method call.

    Interface Interceptor

    Allows interception on any object that implements the target interface. It is much faster than the TransparentProxyInterceptor.

    It only intercepts methods on a single interface. It cannot cast a proxy back to the target object's class or to other interfaces on the target object.

    Virtual Method Interceptor

    Calls are much faster than the Transparent Proxy Interceptor.

    Interception only happens on virtual methods. You must set up interception at object creation time and cannot intercept an existing object.


       所以,你有注意到我们DAL中的三个方法都是virtual。最后输出:

    PreMethodCalling: DAL.MethodForLoggingA()
    Called MethodForLoggingA
    PostMethodCalling: DAL.MethodForLoggingA() ->
    PreMethodCalling: DAL.MethodForLoggingB()
    Called MethodForLoggingB
    PostMethodCalling: DAL.MethodForLoggingB() ->
    PreMethodCalling: DAL.MethodForLoggingC(8)
    Called MethodForLoggingC 8
    PostMethodCalling: DAL.MethodForLoggingC() –>


       您可以对篇文章也感兴趣:

       使用EnterpriseLibrary的PIAB与Unity搭建简单AOP框架

       希望这篇POST对您开发有帮助。


    作者:Petter Liu
    出处:http://www.cnblogs.com/wintersun/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    该文章也同时发布在我的独立博客中-Petter Liu Blog

  • 相关阅读:
    学习进度报告2021/4/5
    学习进度报告2021/4/4
    学习进度报告2021/4/3
    学习进度报告2021/4/2
    学习进度报告2021/4/1
    学习进度报告2021/3/31
    《学会提问》读书笔记3
    学习进度报告2021/3/30
    MySQL入门——如何进行主从配置
    MySQL入门详解——事务、锁、优化
  • 原文地址:https://www.cnblogs.com/wintersun/p/2073697.html
Copyright © 2011-2022 走看看