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(控制反转),不是一种技术,只是一种思想,一个重要的面相对象编程的法则,它能知道我们如何设计出松耦合,更优良的程序.传统应用程 ...
随机推荐
- 环境变量PATH、cp命令、mv命令、文档查看cat/more/less/head/tail 各个命令的使用介绍
第2周第2次课(3月27日) 课程内容: 2.10 环境变量PATH2.11 cp命令2.12 mv命令2.13 文档查看cat/more/less/head/tail 2.10 环境变量PATH P ...
- 第一次c语言作业。
第一次c语言作业 作业1 2.1 你对软件工程专业或者计算机科学与技术专业了解是怎样? 我认为计算机科学与技术是研究信息过程.用以表达此过程的信息结构和规则及其在信息处理系统中实现的学科.这门学科是为 ...
- java调用webservice,比较简单方便的方法。
首先,请同学们自行了解webservice的基础知识. 个人理解,webservice约等于使用http+xml技术进行跨平台的数据交互. http和xml我们都很熟悉了,把他们两个组合到一起就是we ...
- 如何使用modelarts训练海量数据
在modelarts上使用notebook上使用evs空间默认大小是5G,能满足大部分文本和图片训练模型的需求.如果训练数据稍微超过这个限额,可以适当的扩增下空间.但如果训练对象是视频,或是实际生成过 ...
- Hadoop 维护总结
1. 启动 history ./sbin/mrjobhistorydaemon.sh start historyserver ./sbin/yarn-daemon.sh start proxyserv ...
- 小白学 Python 爬虫(17):Requests 基础使用
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- MVC方法的返回值类型
MVC方法返回值类型 ModelAndView返回值类型: 1.当返回为null时,页面不跳转. 2.当返回值没有指定视图名时,默认使用请求名作为视图名进行跳转. 3.当返回值指定了视图名,程序会按照 ...
- CoderForces-375D
You have a rooted tree consisting of n vertices. Each vertex of the tree has some color. We will ass ...
- HDU3849-By Recognizing These Guys, We Find Social Networks Useful(无向图的桥)
By Recognizing These Guys, We Find Social Networks Useful Time Limit: 2000/1000 MS (Java/Others) ...
- Jquery判断当前时PC端,移动端,平板端屏幕
$(function(){ // console.log(navigator.userAgent); var os = function (){ var ua = navi ...