Unity 依赖注入容器的AOP扩展

使用EntLib\PIAB Unity 实现动态代理

 1 using System;
 2 using Unity;
 3 using Unity.Interception;
 4 using Unity.Interception.Interceptors.InstanceInterceptors.InterfaceInterception;
 5 using Unity.Interception.PolicyInjection.Pipeline;
 6 using Unity.Interception.PolicyInjection.Policies;
 7 namespace FrameworkConsole
 8 {
 9     public class UnityAOP
10     {
11         public static void Show()
12         {
13             IUnityContainer container = new UnityContainer();//声明一个容器
14             container.RegisterType<IBusiness, Business>();//注册IBusiness
15             IBusiness bus = container.Resolve<IBusiness>();//获取 IBusiness 对象
16             bus.DoSomething();//调用
17 
18             Console.WriteLine("********************");
19             container.AddNewExtension<Interception>();
20             container.RegisterType<IBusiness, Business>()//注册IBusiness
21                 .Configure<Interception>()//配置拦截
22                 .SetInterceptorFor<IBusiness>(new InterfaceInterceptor());//设置拦截器
23             bus = container.Resolve<IBusiness>();//重新获取 IBusiness 对象
24             bus.DoSomething();//调用
25             Console.Read();
26         }
27         
28     }
29 }
View Code

业务层

 1     #region 业务
 2     [ExceptionHandlerAttribute(Order = 3)]
 3     [LogHandlerAttribute(Order = 2)]
 4     [AfterLogHandlerAttribute(Order = 5)]
 5     public interface IBusiness
 6     {
 7         void DoSomething();
 8     }
 9 
10     public class Business : IBusiness
11     {
12         public void DoSomething()
13         {
14             Console.WriteLine("DoSomething");
15         }
16     }
17     #endregion 业务
18     /*
19     
20     InterfaceInterceptor:在接口的方法上进行标记,这样继承这个接口的类里实现这个接口方法的方法就能被拦截
21     */
View Code

Unity 扩展特性

 1    #region 特性
 2 
 3     public class LogHandlerAttribute : HandlerAttribute
 4     {
 5         public override ICallHandler CreateHandler(IUnityContainer container)
 6         {
 7             return new LogHandler() { Order = this.Order };
 8         }
 9     }
10 
11     public class ExceptionHandlerAttribute : HandlerAttribute
12     {
13         public override ICallHandler CreateHandler(IUnityContainer container)
14         {
15             return new ExceptionHandler() { Order = this.Order };
16         }
17     }
18 
19     public class AfterLogHandlerAttribute : HandlerAttribute
20     {
21         public override ICallHandler CreateHandler(IUnityContainer container)
22         {
23             return new AfterLogHandler() { Order = this.Order };
24         }
25     }
26     #endregion 特性
View Code

特性对应的行为

 1     #region 特性对应的行为
 2 
 3     public class LogHandler : ICallHandler
 4     {
 5         public int Order { get; set; }
 6         /// <summary>
 7         /// 
 8         /// </summary>
 9         /// <param name="input">方法调用的参数列表</param>
10         /// <param name="getNext"></param>
11         /// <returns></returns>
12         public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
13         {
14             Console.WriteLine("日志已记录,Message:{0},Ctime:{1}", "logInfo", DateTime.Now);
15             return getNext()(input, getNext);//先记录日志后,执行下一步操作
16         }
17     }
18 
19 
20     public class ExceptionHandler : ICallHandler
21     {
22         public int Order { get; set; }
23         public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
24         {
25             IMethodReturn methodReturn = getNext()(input, getNext);//先执行下一步操作,再回来校验执行结果是否发生异常
26             if (methodReturn.Exception == null)
27             {
28                 Console.WriteLine("无异常");
29             }
30             else
31             {
32                 Console.WriteLine($"异常:{methodReturn.Exception.Message}");
33             }
34             return methodReturn;
35         }
36     }
37 
38     public class AfterLogHandler : ICallHandler
39     {
40         public int Order { get; set; }
41         public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
42         {
43             IMethodReturn methodReturn = getNext()(input, getNext);//先执行下一步操作,再回来记录完成日志
44             Console.WriteLine("完成日志,Message:{0},Ctime:{1},计算结果{2}", "AfterLog", DateTime.Now, methodReturn.ReturnValue);
45             return methodReturn;
46         }
47     }
48     #endregion 特性对应的行为
View Code

跟踪程序执行过程会发现 程序执行顺序:记录日志=>异常检测=>完成日志=>业务方法=>完成日志=>异常检测

这里程序执行的顺序类似MVC管道模型 典型的俄罗斯套娃模式

把这些业务结合配置文件改成可配置

配置文件Unity.Config

 1 <configuration>
 2   <configSections>
 3     <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/>
 4     <!--Microsoft.Practices.Unity.Configuration.UnityConfigurationSection-->
 5   </configSections>
 6   <unity>
 7     <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/>
 8     <containers>
 9       <container name="aop">
10         <extension type="Interception"/>
11         <register type="FrameworkConsole.IBusiness,FrameworkConsole" mapTo="FrameworkConsole.Business,FrameworkConsole">
12           <interceptor type="InterfaceInterceptor"/>
13           <interceptionBehavior type="FrameworkConsole.UnityWay.MonitorBehavior, FrameworkConsole"/>
14 
15           <interceptionBehavior type="FrameworkConsole.UnityWay.LogBeforeBehavior, FrameworkConsole"/>
16           <interceptionBehavior type="FrameworkConsole.UnityWay.ParameterCheckBehavior, FrameworkConsole"/>
17           <interceptionBehavior type="FrameworkConsole.UnityWay.CachingBehavior, FrameworkConsole"/>
18           <interceptionBehavior type="FrameworkConsole.UnityWay.ExceptionLoggingBehavior, FrameworkConsole"/>
19           <interceptionBehavior type="FrameworkConsole.UnityWay.LogAfterBehavior, FrameworkConsole"/>
20           
21         </register>
22       </container>
23     </containers>
24   </unity>
25 </configuration>
View Code

配置文件配置值 前一项为类地址,后一项为dll地址

另外记得添加Unity.Interception.Configuration.dll

配置行为

 1      public class CachingBehavior : IInterceptionBehavior
 2     {
 3         public IEnumerable<Type> GetRequiredInterfaces()
 4         {
 5             return Type.EmptyTypes;
 6         }
 7 
 8         public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
 9         {
10             Console.WriteLine("CachingBehavior");
11             return getNext().Invoke(input, getNext);
12         }
13 
14         public bool WillExecute
15         {
16             get { return true; }
17         }
18     }
View Code
 1     public class ExceptionLoggingBehavior : IInterceptionBehavior
 2     {
 3         public IEnumerable<Type> GetRequiredInterfaces()
 4         {
 5             return Type.EmptyTypes;
 6         }
 7 
 8         public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
 9         {
10             Console.WriteLine("ExceptionLoggingBehavior");
11             IMethodReturn methodReturn = getNext()(input, getNext);
12             if (methodReturn.Exception == null)
13             {
14                 Console.WriteLine("无异常");
15             }
16             else
17             {
18                 Console.WriteLine($"异常:{methodReturn.Exception.Message}");
19             }
20             return methodReturn;
21         }
22 
23         public bool WillExecute
24         {
25             get { return true; }
26         }
27     }
View Code
 1      public class LogAfterBehavior : IInterceptionBehavior
 2     {
 3         public IEnumerable<Type> GetRequiredInterfaces()
 4         {
 5             return Type.EmptyTypes;
 6         }
 7 
 8         public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
 9         {
10             Console.WriteLine("LogAfterBehavior");
11             foreach (var item in input.Inputs)
12             {
13                 Console.WriteLine(item.ToString());//反射获取更多信息
14             }
15             IMethodReturn methodReturn = getNext()(input, getNext);
16             Console.WriteLine("LogAfterBehavior" + methodReturn.ReturnValue);
17             return methodReturn;
18         }
19 
20         public bool WillExecute
21         {
22             get { return true; }
23         }
24     }
View Code
 1      public class LogBeforeBehavior : IInterceptionBehavior
 2     {
 3         public IEnumerable<Type> GetRequiredInterfaces()
 4         {
 5             return Type.EmptyTypes;
 6         }
 7 
 8         public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
 9         {
10             Console.WriteLine("LogBeforeBehavior");
11             foreach (var item in input.Inputs)
12             {
13                 Console.WriteLine(item.ToString());//反射获取更多信息
14             }
15             return getNext().Invoke(input, getNext);
16         }
17 
18         public bool WillExecute
19         {
20             get { return true; }
21         }
22     }
View Code
 1     /// <summary>
 2     /// 性能监控的AOP扩展
 3     /// </summary>
 4     public class MonitorBehavior : IInterceptionBehavior
 5     {
 6         public IEnumerable<Type> GetRequiredInterfaces()
 7         {
 8             return Type.EmptyTypes;
 9         }
10 
11         public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
12         {
13             Console.WriteLine(this.GetType().Name);
14             string methodName = input.MethodBase.Name;
15             Stopwatch stopwatch = new Stopwatch();
16             stopwatch.Start();
17 
18             var methodReturn = getNext().Invoke(input, getNext);//后续逻辑执行
19 
20             stopwatch.Stop();
21             Console.WriteLine($"{this.GetType().Name}统计方法{methodName}执行耗时{stopwatch.ElapsedMilliseconds}ms");
22 
23             return methodReturn;
24         }
25 
26         public bool WillExecute
27         {
28             get { return true; }
29         }
30     }
View Code
 1      public class ParameterCheckBehavior : IInterceptionBehavior
 2     {
 3         public IEnumerable<Type> GetRequiredInterfaces()
 4         {
 5             return Type.EmptyTypes;
 6         }
 7 
 8         public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
 9         {
10             Console.WriteLine("ParameterCheckBehavior");
11             Console.WriteLine("参数检测无误");
12             return getNext().Invoke(input, getNext);
13         }
14 
15         public bool WillExecute
16         {
17             get { return true; }
18         }
19     }
View Code

调用

1             ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
2             fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory , "Unity.Config");
3             Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
4 
5             UnityConfigurationSection configSection = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
6             configSection.Configure(container, "aop");
7 
8             bus = container.Resolve<IBusiness>();//重新获取 IBusiness 对象
9             bus.DoSomething();//调用
View Code

程序执行顺序(按配置文件顺序执行):监控=>LogBefore=>参数检测=>缓存=>异常检测=>LogAfter=>业务方法=>LogAfter=>异常检测=>监控

微软文档:

System.Configuration https://docs.microsoft.com/zh-cn/dotnet/api/system.configuration?view=netframework-4.8

IUnityContainer https://docs.microsoft.com/zh-cn/previous-versions/msp-n-p/ee649880%28v%3dpandp.10%29

posted @ 2019-10-31 17:48  德乌姆列特  阅读(244)  评论(0编辑  收藏  举报