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