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 依赖注入之二

    出处:https://www.cnblogs.com/chengxuzhimei/p/5198381.html

    ======================================================================

    Unity的三种Interceptor的区别

    Unity默认提供了三种拦截器:TransparentProxyInterceptor、InterfaceInterceptor、VirtualMethodInterceptor。

    TransparentProxyInterceptor:代理实现基于.NET Remoting技术,它可拦截对象的所有函数。缺点是被拦截类型必须派生于MarshalByRefObject。示例如下:

    复制代码
     1 public class MyObject : MarshalByRefObject
     2 {
     3   public String Name { get; set; }
     4 }
     5 
     6 IUnityContainer unityContainer = new UnityContainer();
     7 
     8 unityContainer.AddNewExtension<Interception>();
     9 unityContainer.RegisterType<MyObject>(new Interceptor<TransparentProxyInterceptor>(), new InterceptionBehavior(new NotifyPropertyChangedBehavior()));
    10 
    11 MyObject myObject = unityContainer.Resolve<MyObject>();
    12 
    13 ((INotifyPropertyChanged)myObject).PropertyChanged += new PropertyChangedEventHandler((sender, e) => Console.WriteLine(e.PropertyName));
    14 
    15 myObject.Name = “hello, world”;
    复制代码

    说明:NotifyPropertyChangedBehavior的代码,请参考 Unity Behaviors for Interception 中的内容

    InterfaceInterceptor:只能对一个接口做拦截,好处时只要目标类型实现了指定接口就可以拦截。示例如下:

    复制代码
     1 public class MyObject2 : IServiceProvider
     2 {
     3 
     4   #region IServiceProvider Members
     5 
     6   public object GetService(Type serviceType)
     7   {
     8     return null;
     9   }
    10 
    11   #endregion
    12 }
    13 
    14 public sealed class MyInterceptionBehavior : IInterceptionBehavior
    15 {
    16   #region IInterceptionBehavior Members
    17 
    18   public Boolean WillExecute
    19   {
    20     get { return true; }
    21   }
    22 
    23   public IEnumerable<Type> GetRequiredInterfaces()
    24   {
    25     return new Type[0];
    26   }
    27 
    28   public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
    29   {
    30     return getNext()(input, getNext);
    31   }
    32 
    33   #endregion
    34 }
    35 
    36 IUnityContainer unityContainer = new UnityContainer();
    37 
    38 unityContainer.AddNewExtension<Interception>();
    39 unityContainer.RegisterType<IServiceProvider, MyObject2>(“MyObject2″,
    40   new Interceptor<InterfaceInterceptor>(),
    41   new InterceptionBehavior<MyInterceptionBehavior>()
    42 );
    43 
    44 IServiceProvider myObject = unityContainer.Resolve<IServiceProvider>(“MyObject2″);
    45 
    46 myObject.GetService(typeof(MyObject2));
    复制代码

    注册类型时需要显示指定被拦截接口类型。

    VirtualMethodInterceptor:对virtual函数进行拦截。缺点是如果被拦截类型没有virtual函数则无法拦截,这个时候如果类型实现了某个特定接口可以改用InterfaceInterceptor。看一个简单示例:

    复制代码
     1 public class MyObject3
     2 {
     3   public virtual void DoWork()
     4   {
     5 
     6   }
     7 }
     8 
     9 IUnityContainer unityContainer = new UnityContainer();
    10 
    11 unityContainer.AddNewExtension<Interception>();
    12 unityContainer.RegisterType<MyObject3>(
    13   new Interceptor<VirtualMethodInterceptor>(),
    14   new InterceptionBehavior<MyInterceptionBehavior>()
    15 );
    16 
    17 MyObject3 myObject = unityContainer.Resolve<MyObject3>();
    18 
    19 myObject.DoWork();
    复制代码

    出处:https://www.cnblogs.com/junchu25/archive/2012/08/10/2631583.html

    您的资助是我最大的动力!
    金额随意,欢迎来赏!
    款后有任何问题请给我留言。

    如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的推荐按钮。
    如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的关注我。(●'◡'●)

    如果你觉得本篇文章对你有所帮助,请给予我更多的鼓励,求打             付款后有任何问题请给我留言!!!

    因为,我的写作热情也离不开您的肯定支持,感谢您的阅读,我是【Jack_孟】!

  • 相关阅读:
    Android App Bundle 使用指南
    Homebrew国内源
    Mac下配置环境变量不生效问题
    CocosCreator1.x配置打包Android App Bundle
    Android读取Json文件的工具类
    Cocos Creator 坐标转换
    XCode真机调试不了,提示"Please reconnect the device"
    Canvas: trying to draw too large(134374464bytes) bitmap.
    Modbus主从关系几点记录
    当前时间加上几天
  • 原文地址:https://www.cnblogs.com/mq0036/p/15393485.html
Copyright © 2011-2022 走看看