JointCode.Aspects,一个基于装饰模式的 Aop 框架
实现 Aop 的方法有很多,有人给总结了一下,至少有以下几种:
Approach 方法 |
Advantages 优点 |
Disadvantages 缺点 |
Remoting Proxies 远程代理 |
Easy to implement, because of the .Net framework support 容易实现,因为有.NET框架的支持。 |
Somewhat heavyweight 微显重量级 仅在接口或MarshalByRefObjects 上使用 |
Derivingfrom ContextBoundObject 从ContextBoundObject 派生 |
Easiest to implement 很容易实现 原生支持调用拦截 |
Very costly in terms of performance 非常昂贵的性能代价 |
Compile-time subclassing 编译时子类化 |
Easiest to understand 很容易理解 |
Interfaces or virtual methods only 仅用于接口或虚方法 |
Runtime subclassing 运行时子类化 |
Easiest to understand 很容易理解 非常灵活 |
Complex implementation (but alreadyexists) 复杂的实现(已经实现) 仅用于接口或虚方法 |
Hooking into the profiler API 分析 API钩子 |
Extremely powerful 极端强大 |
Performance? 性能未知 复杂实现(COM API,需要单独运行等) |
Compile time IL-weaving 编译时 IL织入 |
Very powerful 非常强大 良好的性能 |
Very hard to implement 实现非常困难 |
Runtime IL-weaving 运行时 IL织入 |
Very powerful 非常强大 朗好的性能 |
Very hard to implement 实现非常困难 |
而 JointCode.Aspects 只是一个基于装饰模式来实现方法拦截的 Aop 半成品。
什么是装饰模式,怎么实现方法拦截呢?
用代码来简单解释一下。
1 public class Base 2 { 3 public void Print() 4 { 5 DoPrint(); 6 } 7 protected virtual void DoPrint() 8 { 9 Console.WriteLine("Base.DoPrint...." + (City ?? string.Empty)); 10 } 11 } 12 public class Derived : Base 13 { 14 protected sealed override void DoPrint() 15 { 16 Console.WriteLine("Derived.DoPrint"); 17 base.Print(); 18 } 19 }
如上所示,假设我们有一个要拦截的类 Base,我们要拦截其虚方法 Print。那么我们只要从这个 Base 类派生出一个 Derived 类,然后在 Derived 类中重写这个方法,并在重写的方法中调用原来的方法,这样就实现了简单的方法拦截。
为什么说是半成品呢?
开发这个框架时,作者的本意是想把这个框架用到自己的 IoC 框架(My.IoC)中,让 IoC 负责对象创建,而 JointCode.Aspects 则负责方法注入,这样可以通过配置实现非常灵活的对象生成。因此 JointCode.Aspects 只是在运行时动态生成被装饰类的派生类从而实现方法注入,但它并不负责为我们创建该派生类的对象,所以我说它是一个半成品。
使用场景设想
比如说,我们可以设想一下这样的场景:我们需要执行某些需要验证身份的操作(例如删除文件、访问网络等), 我们为这些操作分别设计了一个服务,并将这些服务注册到 IoC 中。由于身份验证这个动作是共同的,我们可以将这个动作从业务代码中抽取出来,写到一个公共方法中。然后,当我们在 IoC 中注册这些服务时,我们可以指定将身份验证动作植入这些操作中,从而在运行时动态改变业务流程。
一点说明
目前来说,这个框架只是我个人自己在用,并未开源。这篇文章也只是简单介绍一下这个框架,远远没有涉及到这个框架的设计思路,如果您对这个框架感兴趣的话,欢迎您在下面的评论区中提出问题共同讨论。
使用方法
我为这个框架写了一个简单的示例,您可以单击 此处 下载示例源码。至于这个框架的具体使用方法,且容我在以后有必要时再慢慢写出吧。