Unity.Interception(AOP)

        在前面我们学习到的是Unity依赖注入(DI)与统一容器来松散耦合,这个设计已经对我们系统带来了很多的好处。但是我们还会想尝试和遵循单一职责,开放封闭原则。比如我们不应该在我们的Business层去实现日志、校验、缓存、异常处理等工作,Unity的Interception可以帮助我们横切关注点(Crosscutting concerns 即AOP),来独立处理这些关注点。
        什么是横切关注点(AOP)?横切关注点(AOP)是关注影响应用程序的许多区域。例如,你可能需要将信息写入日志文件在应用程序许多不同的区域,横切关注点(AOP)可以帮助你构建一致的应用程序方式与应用程序业务。
常见的LOB应用程序的横切关注点包括:
        1.日记(Log)
        2.校验(Validation
        3.异常处理(Exception handling
        4.瞬时故障处理(Transient fault handling
        5.权限处理(Authentication and authorization
        6.缓存(Caching
        7.性能监控(Performance monitoring
        8.加密(Encryption
        9.映射(Mapping
        10.压缩(Compression
 
        在使用Unity.Interception以前我们先自己写一个简单的AOP:
1.业务接口
    /// <summary>
    /// 接口
    /// </summary>
    public interface ITalk
    {
        void talk(string msg);
    }

2.业务实现

    public class PeopleTalk : ITalk
    {
        private string username;

        private int age;

        public string UserName
        {
            get { return username; }
        }

        public int Age
        {
            get { return age; }
        }

        public PeopleTalk(string userName, int age)
        {
            this.username = userName;
            this.age = age;
        }

        public virtual void talk(string msg)
        {
            Console.WriteLine(msg + "!你好,我是" + username + ",我的年龄" + age);
        }

    }

3.代理对象

    public class TalkProxy : ITalk
    {
        private ITalk talker;

        public TalkProxy(ITalk talker)
        {
            this.talker = talker;
        }

        public void talk(string msg)
        {
            talker.talk(msg);
        }

        public void talk(string msg, string singName)
        {
            talker.talk(msg);
            sing(singName);
        }

        public void sing(string singName)
        {
            Console.WriteLine("唱歌:" + singName);
        }
    }

4.调用

    class Program
    {
        static void Main(string[] args)
        {
            #region 静态代理

            ITalk people = new PeopleTalk("AOP", 18);

            people.talk("No ProXY Test!");

            Console.WriteLine("---------------------------------");

            TalkProxy talker = new TalkProxy(people);

            talker.talk("ProXY Test", "代理");

            #endregion

        }
    }

  代理模式是一种简单的AOP,talk是一个切面,我们可以在代理类中添加日志、校验、异常处理等等。这样我们就实现了,核心关注点与横切关注点的分离。正如Avanade公司的高级方案架构师Adam Magee所说,AOP的核心思想就是”将应用程序中的商业逻辑同对其提供支持的通用服务进行分离“。

 

  下面我们来看看Unity.Interception是如何现实AOP的
 1.在Unity中实现IInterceptionBehavior接口
    /// <summary>
    /// Unity为我们提供了一个IInterceptionBehavior接口需要实现这个接口
    /// 接口为我们提供了三个方式(GetRequiredInterfaces、Invoke、WillExecute)实现
    /// WillExecute表示是否执行该行为,如果是false这个方法被调用时,不会被捕捉。因为我们总是要执行的,所以为true
    /// GetRequiredInterfaces将你想要的接口类型和行为联系起来,我们暂时不需要,所以返回Type.EmptyTypes
    /// Invoke执行方式接口
    /// </summary>
    public class LoggingInterceptionBehavior : IInterceptionBehavior
    {
        public bool WillExecute
        {
            get { return true; }
        }

        public IEnumerable<Type> GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            Console.WriteLine("Method: {0}", input.MethodBase.Name);

            Console.WriteLine("参数:");
            for (var i = 0; i < input.Arguments.Count; i++)
            {
                Console.WriteLine("{0}: {1}", input.Arguments.ParameterName(i), input.Arguments[i]);
            }
            Console.WriteLine("执行前");
            var result = getNext()(input, getNext);//在这里执行方法
            if (result.Exception != null)
            {
                //发生错误记录日志
                Console.WriteLine(String.Format("Method {0} threw exception {1} at {2}", input.MethodBase, result.Exception.Message, DateTime.Now.ToLongTimeString()));
            }
            Console.WriteLine("执行后");
            return result;
        }
    }

2.调用

    class Program
    {
        static void Main(string[] args)
        {
            UnityContainer container = new UnityContainer();
            container.AddNewExtension<Interception>();
            container.RegisterType<ITalk, PeopleTalk>(
                new InjectionConstructor("AOP", 18), 
                new Interceptor<InterfaceInterceptor>(), 
                new InterceptionBehavior<LoggingInterceptionBehavior>());
            ITalk talker = container.Resolve<ITalk>();
            talker.talk("ProXY Test!");
        }
    }

以上基本完成了简单的Unity.Interception 

当然在Unity中不只有InterfaceInterceptor一种拦截器,它还包含其它两种拦截器:TransparentProxyInterceptor 与 VirtualMethodInterceptor 

这里就不详细介绍就提一下这三种:

InterfaceInterceptor只要是继承接口的方法都会被拦截。
TransparentProxyInterceptor只要是继承类使用的方法都会被拦截。
VirtualMethodInterceptor 意思是虚方法拦截器,继承类的方法必须是Virtual的,和继承类必须是公开的。满足这两个条件即可

 
 
 
----------------------------------------------------------------------------------------------------------------
 
同时在这里我还是没有回答在我Unity4.0的使用 中“一只老菜鸟”所提的问题,不过我会努力的
以上是本人比较初级的处理,主要用于本人学习Unity的一个记录

如果有不懂的可以先查看

Unity 依赖注入之一

Unity 依赖注入之二

 

 

 

 

 

 

posted @ 2016-02-18 15:36  程序之美~我爱上编程  阅读(3148)  评论(1编辑  收藏  举报