zoukankan      html  css  js  c++  java
  • 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 依赖注入之二

  • 相关阅读:
    使用 Dockerfile 定制镜像
    UVA 10298 Power Strings 字符串的幂(KMP,最小循环节)
    UVA 11090 Going in Cycle!! 环平均权值(bellman-ford,spfa,二分)
    LeetCode Best Time to Buy and Sell Stock 买卖股票的最佳时机 (DP)
    LeetCode Number of Islands 岛的数量(DFS,BFS)
    LeetCode Triangle 三角形(最短路)
    LeetCode Swap Nodes in Pairs 交换结点对(单链表)
    LeetCode Find Minimum in Rotated Sorted Array 旋转序列找最小值(二分查找)
    HDU 5312 Sequence (规律题)
    LeetCode Letter Combinations of a Phone Number 电话号码组合
  • 原文地址:https://www.cnblogs.com/chengxuzhimei/p/5198381.html
Copyright © 2011-2022 走看看