Unity 依赖注入容器的AOP扩展
使用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扩展的更多相关文章
- WPF PRISM开发入门二(Unity依赖注入容器使用)
这篇博客将通过一个控制台程序简单了解下PRISM下Unity依赖注入容器的使用.我已经创建了一个例子,通过一个控制台程序进行加减乘除运算,项目当中将输入输出等都用接口封装后,结构如下: 当前代码可以点 ...
- Unity轻量级依赖注入容器
一.前言 Unity是一个轻量级的可扩展的依赖注入容器,支持构造函数,属性和方法调用注入.在Nuget里安装unity
- IoC 依赖注入容器 Unity
原文:IoC 依赖注入容器 Unity IoC 是什么? 在软件工程领域,“控制反转(Inversion of Control,缩写为IoC)”是一种编程技术,表述在面向对象编程中,可描述为在编译时静 ...
- Unity依赖注入使用详解
写在前面 构造器注入 Dependency属性注入 InjectionMethod方法注入 非泛型注入 标识键 ContainerControlledLifetimeManager单例 Unity注册 ...
- 通过Unity依赖注入
前言 Unity容器的思想起始于我在为Web Client Sofitware Factory项目工作的时候,微软的patterns&practices团队已经使用依赖注入的概念好几年了在那时 ...
- Unity依赖注入
一.简介 Unity是一个轻量级的可扩展的依赖注入容器,支持构造函数,属性和方法调用注入.Unity可以处理那些从事基于组件的软件工程的开发人员所面对的问题.构建一个成功应用程序的关键是实现非常松散的 ...
- .NET 用 Unity 依赖注入——概述注册和解析类型(1)
本文内容 Unity 概述 环境 一个真实的例子 类型注册(Type Registrations) 解析类型(Resolving Types) 跳槽,新公司使用了 Unity,初步看了一下,公司的使用 ...
- C#实例 Unity依赖注入使用
Unity是一个轻量级的可扩展的依赖注入容器,支持构造函数,属性和方法调用注入.Unity可以处理那些从事基于组件的软件工程的开发人员所面对的问 题.构建一个成功应用程序的关键是实现非常松散的耦合设计 ...
- c# Unity依赖注入WebService
1.IOC与DI简介 IOC全称是Inversion Of Control(控制反转),不是一种技术,只是一种思想,一个重要的面相对象编程的法则,它能知道我们如何设计出松耦合,更优良的程序.传统应用程 ...
随机推荐
- Leetcode_01【两数之和】
文章目录: 题目 脚本一及注释 脚本逻辑 脚本二及注释 脚本逻辑 题目: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. ...
- 关于python中的列表遍历注意事项
在开发过程中,很容易出现以下的错误: 可以看出:假如删除列表的元素之后直接执行continue,那么遍历的时候就会落下一个元素. 那么怎么解决这个问题呢? 首先 : 我们尝试把continue去掉: ...
- Block-wise 2D kernel PCA/LDA for face recognition-笔记
In the present work, we propose a framework for kernel-based 2D feature extraction algorithms tailor ...
- redis数据类型--zset
数据结构: zset是有序的,不运行重复的,带有分值score的 数据结构对比: 操作命令: zadd myzset 10 java 20 python 20 ruby 40 mysql 50 php ...
- shell 替换文本中的某个符号为换行符
替换后为: 0.06774 脚本: :%s/,"/\r/g
- .NETCore 访问国产达梦数据库
前言 武汉达梦数据库有限公司成立于2000年,为中国电子信息产业集团(CEC)旗下基础软件企业,专业从事数据库管理系统的研发.销售与服务,同时可为用户提供大数据平台架构咨询.数据技术方案规划.产品部署 ...
- 使用 Spring 提供的 restTemplate 完成 Http 服务消费
RestTemplate 介绍 RestTemplate 是 Spring 提供的用于访问 Rest 服务的客户端,RestTemplate 提供了多种便捷访问远程 Http 服务的方法,能够大大提高 ...
- 牛客练习赛32 B题 Xor Path
链接:https://ac.nowcoder.com/acm/contest/272/B来源:牛客网 题目描述 给定一棵n个点的树,每个点有权值.定义表示 到 的最短路径上,所有点的点权异或和. ...
- 使用iCamera 测试MT9F002 1400w高分辨率摄像头说明 续集2
使用iCamera 测试MT9F002 1400w高分辨率摄像头说明 续集2 本方案测试三种分辨率输出(其他更多分辨率设置,可以参考手册配置) 3776*3288=1241万像素 3776*2832= ...
- Spring 学习,看松哥这一篇万余字干货就够了!
1. Spring 简介 我们常说的 Spring 实际上是指 Spring Framework,而 Spring Framework 只是 Spring 家族中的一个分支而已.那么 Spring 家 ...