• Unity 依赖注入容器的AOP扩展


    使用EntLibPIAB 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

  • 相关阅读:
    Ado.Net基础拾遗一:读取数据
    Linq 简明教程
    ASP.NET MVC DropdownList的使用
    inner join, left join ,right join 结果
    C#基础之 派生类
    SQL Server 笔试题总结
    SQL Server 基础 之 CASE 子句
    昨晚京东校招笔试,没考一道.net,全考java了
    利用scrapy和MongoDB来开发一个爬虫
    linux 获取网卡的IP地址
  • 原文地址:https://www.cnblogs.com/Dewumu/p/11772733.html
Copyright © 2020-2023  润新知