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_孟】!

原文地址:https://www.cnblogs.com/mq0036/p/15393485.html