(翻译) 使用Unity进行AOP对象拦截
Unity 是一款知名的依赖注入容器( dependency injection container) ,其支持通过自定义扩展来扩充功能。
在Unity软件包内 默认包含了一个对象拦截(Interception)扩展定义。
本篇文章将介绍如何使用对象拦截(Interception)来分离横切关注点(Separation of cross-cutting concerns)。
对象拦截简介
对象拦截(Interception)是一种 AOP(Aspect-oriented programming)编程的实践方法。
其可帮助你保持业务类的纯净,而无需考虑诸如日志和缓存等外围关注点(other concerns)。
在.NET中,实现AOP有多种方法。
一种方式是采用编译后( post-compiler)处理方式,例如 PostSharp。在编译后( after compilation),PostSharp通过修改IL代码来注入(injects)横切代码。
相反地,对象拦截(Interception)是在运行时(Runtime)执行的,同时也意味着会有一些限制。依据不同的拦截器实现,会有如下这些约束:
- 透明代理拦截器(Transparent Proxy Interceptor):需要定义接口(interface),或者要求类继承(inherit)自MarshalByRefObject。
- 接口拦截器(Interface Interceptor):需要定义接口。
- 虚方法拦截器(Virtual Method Interceptor):仅需要方法被定义成virtual方法。
对象拦截如何工作
当从Unity容器请求目标对象时,将不会获取到已配置的类的实例。
实际上,将得到一个动态生成的代理对象(dynamically generated proxy object),或者一个衍生类(derived class)。
如果调用代理对象的一个方法,将可以在被调用方法执行前或执行后执行一些额外行为的代码。
那些定义行为的类需要实现ICallHandler接口。
通过这些行为定义,我们可以访问方法调用的参数列表(arguments),可以吞噬异常(swallow exceptions),或者返回自定义的异常( return custom exceptions)。
附带提一下,在不使用 Unity container的条件下,也是可以使用 Unity interception的。
示例:将异常和方法调用参数列表记录到日志中
在下面的示例中,我们将创建两个自定义的行为(behaviors),都实现了ICallHandler接口:
- LoggerCallHandler:将方法调用参数列表(method arguments)记录到日志中。
- ExceptionLoggerCallHandler:当发生异常时,将方法调用参数列表和调用栈信息记录到日志中。
ExceptionLoggerCallHandler定义如下:
internal class ExceptionLoggerCallHandler : ICallHandler
{
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
// before invoking the method on the original target
Console.WriteLine(String.Format("Invoking method {0} at {1} ", input.MethodBase, DateTime.Now.ToString() )); // invoke the next behavior in the chain
IMethodReturn result = getNext()(input, getNext); // after invoking the method on the original target
if (result.Exception != null)
{
Console.WriteLine("Exception occured: " + result.Exception.Message); Console.WriteLine("Parameters:");
foreach (var parameter in input.Arguments)
{
Console.WriteLine(parameter.ToString());
} Console.WriteLine("StackTrace:");
Console.WriteLine(Environment.StackTrace);
} return result;
} public int Order { get; set; }
}
为了将行为应用到方法上,我们需要创建相应的HandlerAttribute来创建行为的实例。
internal class ExceptionLoggerAttribute : HandlerAttribute
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new ExceptionLoggerCallHandler();
}
}
在这个示例中,我们创建一个简单的计算器类。
同时为了使用接口拦截( Interface Interception),我们还需创建一个接口类型,这样才能应用指定的行为:
public interface ICalculator
{
[Logger]
int Add(int first, int second); [ExceptionLogger]
int Multiply(int first, int second);
}
计算器类的实现还和常规的一样。
现在我们需要配置(setup)Unity容器:
IUnityContainer container = new UnityContainer();
container.AddNewExtension<Interception>();
container.RegisterType<ICalculator, Calculator>()
.Configure<Interception>()
.SetInterceptorFor<ICalculator>(new InterfaceInterceptor()); // Resolve
ICalculator calc = container.Resolve<ICalculator>(); // Call method
calc.Add(, );
当在容器上通过调用Resolve方法来尝试获得一个Calculate类的实例时,将会得到一个代理类(proxy class)实例。
它的名字可能类似于 ‘DynamicModule.ns.Wrapped_ICalculator_83093f794c8d452e8af4524873a017de’。
当调用此包装类(the wrapper class)的某个方法时,CallHandlers将会被执行。
总结
Unity并不提供一个完整的AOP框架,因此使用它会有一些限制。但不管怎样,使用Unity对象拦截功能来实现一些基本的AOP需求已经足够了。
原文链接:AOP - Interception with Unity 2.0 (http://www.palmmedia.de/Blog/2010/9/26/aop-interception-with-unity-20)
(翻译) 使用Unity进行AOP对象拦截的更多相关文章
- 运用Unity实现AOP拦截器
运用Unity实现AOP拦截器[结合异常记录实例] 本篇文章将通过Unity实现Aop异常记录功能:有关Unity依赖注入可以看前两篇文章: 1:运用Unity实现依赖注入[结合简单三层实例] 2:运 ...
- 运用Unity实现AOP拦截器[结合异常记录实例]
本篇文章将通过Unity实现Aop异常记录功能:有关Unity依赖注入可以看前两篇文章: 1:运用Unity实现依赖注入[结合简单三层实例] 2:运用Unity实现依赖注入[有参构造注入] 另早期 ...
- Unity Ioc 依赖倒置及Untity AOP被动拦截/自动拦截
各位博友金安,首先声明这是一篇转载的博客,原文链接:https://www.cnblogs.com/scottpei/archive/2013/01/08/2851087.html 十年河东,十年河西 ...
- 我心中的核心组件(可插拔的AOP)~第十三回 实现AOP的拦截组件Unity.Interception
回到目录 说在前 本节主要说一下Unity家族里的拦截组件,对于方法拦截有很多组件提供,基本上每个Ioc组件都有对它的实现,如autofac,它主要用在orchard项目里,而castle也有以拦截的 ...
- AOP实现拦截对象以及获取切入目标方法和注解
AOP实现拦截对象以及获取切入目标方法和注解 一.JoinPoint是什么? AspectJ使用org.aspectj.lang.JoinPoint接口表示目标类连接点对象,如果是环绕增强时,使用 o ...
- 运用Unity结合PolicyInjection实现拦截器
运用Unity结合PolicyInjection实现拦截器[结合操作日志实例] 上一篇文章我们通过Unity自身Unity.InterceptionExtension.IInterceptionBeh ...
- AOP之拦截函数调用链实现
AOP之拦截函数调用链实现 定义函数A,B,C,调用A->B->C,这样就形成了函数静态调用链,而AOP要做的是能动态的添加多个B,形成A->B1->B2->B3...- ...
- .NET中使用unity实现aop
Unity是一款知名的依赖注入容器,其支持通过自定义扩展来扩充功能.在Unity软件包内默认包含了一个对象拦截(Interception)扩展定义.本篇文章将介绍如何使用对象拦截功能来帮助你分离横切关 ...
- Ioc 之 Unity的AOP功能
前面我们介绍了Unity的依赖注入功能,现在来介绍下Unity的AOP功能.AOP是面向切面编程,它能够使我们在不改变现有代码结构的情况下额外的为其添加一些功能. 我们还是使用配置文件来对类型进行注入 ...
随机推荐
- webdriver访问各个浏览器驱动下载及安装
这里首先需要查看一下自己安装的selenium版本 查看步骤: windows系统打开cmd命令行输入:pip show selenium查看结果如下: 进入到selenium官网查看版本信息 sel ...
- Linux下运行命令出现is not in the sudoers file的问题
原因: 用户没有加入到sudo的配置文件里. 解决方法: 1.切换到root用户,运行visudo命令: 2.找到root ALL=(ALL) ALL,在下面添加一行 xxx ALL=(ALL) ...
- mingster.com
Good to Great: Why Some Companies Make the Leap... and Others Don'tby Jim Collinshttp://rcm.amazon.c ...
- linux Init分析(原创)
1.uboot的目标就是启动内核kernel: 2.kernel的目的就是启动应用程序,而第一个应用程序即是Init,构建根文件系统. 从uboot初始化配置后,引导内核的启动,启动函数为:start ...
- 5G时代,会有什么奇葩事儿?
在3GPP RAN第187次会议关于5G短码方案的讨论中,中国华为推荐的PolarCode方案获得认可,成为5G控制信道eMBB场景编码的最终解决方案.坦白讲,笔者在读这个新闻的时候,手里备着一本 ...
- [红日安全]Web安全Day3 - CSRF实战攻防
本文由红日安全成员: Once 编写,如有不当,还望斧正. 大家好,我们是红日安全-Web安全攻防小组.此项目是关于Web安全的系列文章分享,还包含一个HTB靶场供大家练习,我们给这个项目起了一个名字 ...
- C++走向远洋——39(指向学生类的指针)
*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:zhizhen.cpp * 作者:常轩 * 微信公众号:Worl ...
- Git 程序员篇
关于 Git Git 背后的故事 伟大的作品总是诞生于伟大的时代,正如 Git 同样诞生于一个英雄辈出.极富纷争的年代. 2005 年,Linux 内核开发社区正面临严峻的挑战:他们不能继续使用 Bi ...
- sql 服务器统计信息简介
sql服务器统计是包含数据分布信息的系统对象.有时,在正则列值中.统计可以在任何支持比较操作的数据类型上创建,例如 > , < , =等. 列表2-15中,从dbo.books表中查看 I ...
- Mac中使用brew安装mysql
若不考虑版本直接执行以下命令 brew install mysql 若要选择版本只要加上@版本即可,例如 brew install mysql@5.7 安装完后启动mysql mysql.server ...