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

 using System;
using Unity;
using Unity.Interception;
using Unity.Interception.Interceptors.InstanceInterceptors.InterfaceInterception;
using Unity.Interception.PolicyInjection.Pipeline;
using Unity.Interception.PolicyInjection.Policies;
namespace FrameworkConsole
{
public class UnityAOP
{
public static void Show()
{
IUnityContainer container = new UnityContainer();//声明一个容器
container.RegisterType<IBusiness, Business>();//注册IBusiness
IBusiness bus = container.Resolve<IBusiness>();//获取 IBusiness 对象
bus.DoSomething();//调用 Console.WriteLine("********************");
container.AddNewExtension<Interception>();
container.RegisterType<IBusiness, Business>()//注册IBusiness
.Configure<Interception>()//配置拦截
.SetInterceptorFor<IBusiness>(new InterfaceInterceptor());//设置拦截器
bus = container.Resolve<IBusiness>();//重新获取 IBusiness 对象
bus.DoSomething();//调用
Console.Read();
} }
}

业务层

     #region 业务
[ExceptionHandlerAttribute(Order = )]
[LogHandlerAttribute(Order = )]
[AfterLogHandlerAttribute(Order = )]
public interface IBusiness
{
void DoSomething();
} public class Business : IBusiness
{
public void DoSomething()
{
Console.WriteLine("DoSomething");
}
}
#endregion 业务
/* InterfaceInterceptor:在接口的方法上进行标记,这样继承这个接口的类里实现这个接口方法的方法就能被拦截
*/

Unity 扩展特性

    #region 特性

     public class LogHandlerAttribute : HandlerAttribute
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new LogHandler() { Order = this.Order };
}
} public class ExceptionHandlerAttribute : HandlerAttribute
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new ExceptionHandler() { Order = this.Order };
}
} public class AfterLogHandlerAttribute : HandlerAttribute
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new AfterLogHandler() { Order = this.Order };
}
}
#endregion 特性

特性对应的行为

     #region 特性对应的行为

     public class LogHandler : ICallHandler
{
public int Order { get; set; }
/// <summary>
///
/// </summary>
/// <param name="input">方法调用的参数列表</param>
/// <param name="getNext"></param>
/// <returns></returns>
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
Console.WriteLine("日志已记录,Message:{0},Ctime:{1}", "logInfo", DateTime.Now);
return getNext()(input, getNext);//先记录日志后,执行下一步操作
}
} public class ExceptionHandler : ICallHandler
{
public int Order { get; set; }
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
IMethodReturn methodReturn = getNext()(input, getNext);//先执行下一步操作,再回来校验执行结果是否发生异常
if (methodReturn.Exception == null)
{
Console.WriteLine("无异常");
}
else
{
Console.WriteLine($"异常:{methodReturn.Exception.Message}");
}
return methodReturn;
}
} public class AfterLogHandler : ICallHandler
{
public int Order { get; set; }
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
IMethodReturn methodReturn = getNext()(input, getNext);//先执行下一步操作,再回来记录完成日志
Console.WriteLine("完成日志,Message:{0},Ctime:{1},计算结果{2}", "AfterLog", DateTime.Now, methodReturn.ReturnValue);
return methodReturn;
}
}
#endregion 特性对应的行为

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

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

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

配置文件Unity.Config

 <configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/>
<!--Microsoft.Practices.Unity.Configuration.UnityConfigurationSection-->
</configSections>
<unity>
<sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/>
<containers>
<container name="aop">
<extension type="Interception"/>
<register type="FrameworkConsole.IBusiness,FrameworkConsole" mapTo="FrameworkConsole.Business,FrameworkConsole">
<interceptor type="InterfaceInterceptor"/>
<interceptionBehavior type="FrameworkConsole.UnityWay.MonitorBehavior, FrameworkConsole"/> <interceptionBehavior type="FrameworkConsole.UnityWay.LogBeforeBehavior, FrameworkConsole"/>
<interceptionBehavior type="FrameworkConsole.UnityWay.ParameterCheckBehavior, FrameworkConsole"/>
<interceptionBehavior type="FrameworkConsole.UnityWay.CachingBehavior, FrameworkConsole"/>
<interceptionBehavior type="FrameworkConsole.UnityWay.ExceptionLoggingBehavior, FrameworkConsole"/>
<interceptionBehavior type="FrameworkConsole.UnityWay.LogAfterBehavior, FrameworkConsole"/> </register>
</container>
</containers>
</unity>
</configuration>

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

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

配置行为

      public class CachingBehavior : IInterceptionBehavior
{
public IEnumerable<Type> GetRequiredInterfaces()
{
return Type.EmptyTypes;
} public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
Console.WriteLine("CachingBehavior");
return getNext().Invoke(input, getNext);
} public bool WillExecute
{
get { return true; }
}
}
     public class ExceptionLoggingBehavior : IInterceptionBehavior
{
public IEnumerable<Type> GetRequiredInterfaces()
{
return Type.EmptyTypes;
} public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
Console.WriteLine("ExceptionLoggingBehavior");
IMethodReturn methodReturn = getNext()(input, getNext);
if (methodReturn.Exception == null)
{
Console.WriteLine("无异常");
}
else
{
Console.WriteLine($"异常:{methodReturn.Exception.Message}");
}
return methodReturn;
} public bool WillExecute
{
get { return true; }
}
}
      public class LogAfterBehavior : IInterceptionBehavior
{
public IEnumerable<Type> GetRequiredInterfaces()
{
return Type.EmptyTypes;
} public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
Console.WriteLine("LogAfterBehavior");
foreach (var item in input.Inputs)
{
Console.WriteLine(item.ToString());//反射获取更多信息
}
IMethodReturn methodReturn = getNext()(input, getNext);
Console.WriteLine("LogAfterBehavior" + methodReturn.ReturnValue);
return methodReturn;
} public bool WillExecute
{
get { return true; }
}
}
      public class LogBeforeBehavior : IInterceptionBehavior
{
public IEnumerable<Type> GetRequiredInterfaces()
{
return Type.EmptyTypes;
} public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
Console.WriteLine("LogBeforeBehavior");
foreach (var item in input.Inputs)
{
Console.WriteLine(item.ToString());//反射获取更多信息
}
return getNext().Invoke(input, getNext);
} public bool WillExecute
{
get { return true; }
}
}
     /// <summary>
/// 性能监控的AOP扩展
/// </summary>
public class MonitorBehavior : IInterceptionBehavior
{
public IEnumerable<Type> GetRequiredInterfaces()
{
return Type.EmptyTypes;
} public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
Console.WriteLine(this.GetType().Name);
string methodName = input.MethodBase.Name;
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start(); var methodReturn = getNext().Invoke(input, getNext);//后续逻辑执行 stopwatch.Stop();
Console.WriteLine($"{this.GetType().Name}统计方法{methodName}执行耗时{stopwatch.ElapsedMilliseconds}ms"); return methodReturn;
} public bool WillExecute
{
get { return true; }
}
}
      public class ParameterCheckBehavior : IInterceptionBehavior
{
public IEnumerable<Type> GetRequiredInterfaces()
{
return Type.EmptyTypes;
} public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
Console.WriteLine("ParameterCheckBehavior");
Console.WriteLine("参数检测无误");
return getNext().Invoke(input, getNext);
} public bool WillExecute
{
get { return true; }
}
}

调用

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

程序执行顺序(按配置文件顺序执行):监控=>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

Unity 依赖注入容器的AOP扩展的更多相关文章

  1. WPF PRISM开发入门二(Unity依赖注入容器使用)

    这篇博客将通过一个控制台程序简单了解下PRISM下Unity依赖注入容器的使用.我已经创建了一个例子,通过一个控制台程序进行加减乘除运算,项目当中将输入输出等都用接口封装后,结构如下: 当前代码可以点 ...

  2. Unity轻量级依赖注入容器

    一.前言 Unity是一个轻量级的可扩展的依赖注入容器,支持构造函数,属性和方法调用注入.在Nuget里安装unity

  3. IoC 依赖注入容器 Unity

    原文:IoC 依赖注入容器 Unity IoC 是什么? 在软件工程领域,“控制反转(Inversion of Control,缩写为IoC)”是一种编程技术,表述在面向对象编程中,可描述为在编译时静 ...

  4. Unity依赖注入使用详解

    写在前面 构造器注入 Dependency属性注入 InjectionMethod方法注入 非泛型注入 标识键 ContainerControlledLifetimeManager单例 Unity注册 ...

  5. 通过Unity依赖注入

    前言 Unity容器的思想起始于我在为Web Client Sofitware Factory项目工作的时候,微软的patterns&practices团队已经使用依赖注入的概念好几年了在那时 ...

  6. Unity依赖注入

    一.简介 Unity是一个轻量级的可扩展的依赖注入容器,支持构造函数,属性和方法调用注入.Unity可以处理那些从事基于组件的软件工程的开发人员所面对的问题.构建一个成功应用程序的关键是实现非常松散的 ...

  7. .NET 用 Unity 依赖注入——概述注册和解析类型(1)

    本文内容 Unity 概述 环境 一个真实的例子 类型注册(Type Registrations) 解析类型(Resolving Types) 跳槽,新公司使用了 Unity,初步看了一下,公司的使用 ...

  8. C#实例 Unity依赖注入使用

    Unity是一个轻量级的可扩展的依赖注入容器,支持构造函数,属性和方法调用注入.Unity可以处理那些从事基于组件的软件工程的开发人员所面对的问 题.构建一个成功应用程序的关键是实现非常松散的耦合设计 ...

  9. c# Unity依赖注入WebService

    1.IOC与DI简介 IOC全称是Inversion Of Control(控制反转),不是一种技术,只是一种思想,一个重要的面相对象编程的法则,它能知道我们如何设计出松耦合,更优良的程序.传统应用程 ...

随机推荐

  1. mybatis精讲(五)--映射器组件

    目录 前言 标签 select insert|update|delete 参数 resultMap cache 自定义缓存 # 加入战队 微信公众号 前言 映射器之前我们已经提到了,是mybatis特 ...

  2. 使用 Flask 和 Vue.js 来构建全栈单页应用

    在这个教程中,我将向你展示如何将 Vue 的单页面应用和 Flask 后端连接起来. 简单的来说,如果想在 Flask 中使用 Vue 框架是没有什么问题的. 但在实际中存在一个明显的问题就是 Fla ...

  3. 爬取电影top250 电影名 导演 演员 风格 国家 时长 评分 录入mySQL数据库

    import requestsfrom lxml import etreeimport reimport pymysqlimport time conn = pymysql.connect(host= ...

  4. String类中常用的方法

    @Test public void demo(){ // 以下为String中的常用的方法及注释, 最常用的注释前有**标注 String s = "abcdefg123456"; ...

  5. gulp+webpack+angular1的一点小经验(第二部分webpack包起来的angular1)

    又一周过去了,项目也已经做得有点模样了.收集来一些小经验,分享给大家,有疏漏之处,还望指正,海涵. 上周整合了gulp与webpack,那么工具准备差不多了,我们就开始编码吧.编码的框架就是angul ...

  6. zuul+security跨域Cors问题解决

    zuul+security跨域Cors问题解决 简介 场景 在服务后台都会出现跨域cors问题,不过一般spring解决起来比较方便,在框架+框架的基础上,问题就显得特别明显了,各种冲突,不了解源码的 ...

  7. HDU 5121 Just A Mistake

    Just A Mistake Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) ...

  8. Spring Cloud第八篇 | Hystrix集群监控Turbine

    ​ 本文是Spring Cloud专栏的第八篇文章,了解前七篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring Clo ...

  9. 联合查询和数据库设计e-r图

    联合查询: 联合查询的关键字是: union 基本含义 联合查询就是将两个select语句的查询结果“层叠”到一起成为一个“大结果”. 两个查询结果的能够进行“联合”的先觉条件是:结果字段数相等. 就 ...

  10. Day 06 流程控制和爬虫基础2

    目录 if 判断 单分支结构 双分支结构 多分支结构 for循环 for循环的基本用法 for循环嵌套 break continue 爬虫基础2 爬取豆瓣TOP250 爬取豆瓣数据接口(异步数据) 爬 ...