最近公司分配了项任务,让我调查一下.NET世界中的AOP。需求有四
- 什么是AOP?有什么用途?
- AOP的编程模型
- .NET世界中的AOP框架介绍极其评比
- 最佳实践
本文将假设读者对AOP的相关原理概念有了一定的了解,直接从第三部分开始。
实现方式
From Ayende Rahien’s blog post
| Approach | Advantages | Disadvantages |
| Remoting Proxies | Easy to implement, because of the .Net framework support | Somewhat heavy weight |
| Deriving from 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 already exists) |
| Hooking into the profiler API | Extremely powerful | Performance? |
| Compile time IL-weaving | Very powerful | Very hard to implement |
| Runtime IL-weaving | Very powerful | Very hard to implement |
来看看具体的缺点
- 使用remoting proxies / ContextBoundObject
- 无法对this的调用进行intercept,因为CLR保证this不会是代理
- 性能影响很大,比如使用继承ContextBoundObject的方式会造成运行时context切换
- SubClassing
- 需要类型不能为sealed且只能override virtual方法。
- 不能改写constructor
- Weaving
- 如果是source code层级的织入,需要对每种.Net支持的语言提供分别的支持
- 无论是source code层级还是IL层级的织入,都有可能在类型变更的时候遭到破坏/给类型造成破坏。
现有的一些.Net的AOP框架
| Project | Status | License | Approach | Document & Support | More Description |
| GPL 2+ Look here for detail | Perhaps Compile time IL injection? | This project is not supported any more. | Relies on Cecil. | ||
| Compile time IL injection | Commercial support. Well documented. | ||||
| Dynamic proxy | Out of date documents | Multipurpose framework | |||
| Custom Complier | Only tested with .Net 1.x | ||||
| Relies on Phoenix | |||||
| ? | |||||
| ? | |||||
| ? | Runtime IL injection | ||||
| ? | Compile time IL injection | Relies on Rapier-LOOM.NET | |||
| Runtime proxy | Well documented. | Multipurpose framework | |||
| Runtime proxy | Out of date documents. | Relies on Cecil. Multipurpose framework | |||
| ? | Static mixins | Relies on Cecil. | |||
| Runtime proxy | Well documented. | Multipurpose framework |
来看几个框架的一些具体介绍
关于几个IL织入的框架
技术上来说,能够支持IL织入的框架是一定能实现AOP的,比如Mono Cecil, MS CCI, MS Phoenix, and Rail。但是由于他们不是专门做AOP的框架,在之后的评比中没有考虑他们。
PIAB
PIAB (The Policy Injection Application Block) 是MS Enterprise Library的一部分。已经内嵌的支持如下aspects
- Authorization
- Exception Handling
- Logging
- Validation
- Performance Counter
- Caching (Caching handler is removed from EntLib 5.0 due to some issues)
Spring.Net
已经内嵌的支持如下aspects。
- Caching
- Exception Handling
- Logging
- Retry
- Transaction Management
- Parameter Validation
Post Sharp
注意Post Sharp对商业应用已不再开源和免费。
以插件的形式支持如下aspects
以插件的形式集成了其他一些著名的框架,但是貌似是Post Sharp 1.5时的事儿了?
最重要的一点:只能inject本assembly中的东西,不能修改其他assembly,这就是为什么我的sample中其他都在调用Models.Tester,唯独Post'Sharp.Interception把Tester的实现copy了一份:要intercept的Buy方法的调用在Tester里。
LinFu
由于PostSharp已经收费,所以就想找一款同样是IL weaving方式的开源AOP框架。目前比较活跃的貌似就属LinFu了,但是实践起来却问题多多(单指AOP方面,这个框架还支持IoC、动态代理等)。比如
文档老旧,很多和最新版(2.3)对不上。
配置上(编辑csproj文件)不支持对指定方法的interception,这是最让人抓狂的,来看
/>