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

posted on 2011-06-06 16:28  PetterLiu  阅读(3384)  评论(2编辑  收藏  举报