PostSharp - 面向方面系统(转)
2008-08-15 10:16
155 查看
PostSharp 是一个令人兴奋的项目,他结合了 MSBuild Task 和 MSIL Injection 技术,从另外一个角度实现 AOP 编程。试用过后你会感觉到其便利性,我们和以往基于 Dynamic Proxy 方式的 AOP 解决方案做个比较。
由于采用 MSIL Injection,因此静态代码注入的执行效率要高于使用 Reflection Emit。
使用 MSBuild Task,使得开发人员可以像使用编译器内置 Attribute 那样使用 AOP。
可以拦截任意方法,而 Dynamic Proxy 方式的 AOP 往往采取继承方式来拦截 Virtual 方法。
拥有更多的控制权。包括中断执行流程,修改参数和返回值等等。
还可以拦截 Field Access、Exception 等操作。
无需将对象创建代码改成 "new proxy()",更加透明。
可以使用通配符进行多重拦截匹配。
静态注入带来的问题更多的是注入代码的质量和调试复杂度。
我们写一个简单的例子,看看效果。
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using PostSharp.Laos;
[Serializable]
public class AopMethodAttribute : OnMethodBoundaryAspect
public class MyClass
MyClass o = new MyClass();
o.Test(123);
输出:
OnEntry:MyClass.Int32 Test(Int32)
i=123
Test:123
OnExit...
整个过程非常简单:
1. 创建一个继承自 OnMethodBoundaryAspect 的特性类,用于拦截方法。
2. override 特定的方法,执行拦截操作。方法参数提供了各种操作能力。
3. 向目标方法添加特性。
4. 编译,执行。
或许你会好奇,AopMethodAttribute 是如何被创建实例,并被执行的呢?
1. 注意编译时 VS2005 Output 窗口的输出内容,你会看到如下内容。其实 PostSharp 提供了一个 MSBuild Task,在我们每次编译时会调用它执行一些注入操作。
PostSharp 1.0 [1.0.4.162] - Copyright (c) Gael Fraiteur and Community, 2006.
2. 用反编译工具看看注入后的方法内容。看完这些代码,就算我不说,你也能明白它是如何实现拦截的了。
static MyClass()
public int Test(int i)
我们可以使用通配符拦截更多的内容,以简化我们的编码。
[AopMethod(AttributeTargetMembers="T*")]
public class MyClass
{
public int T1(int i)
{
Console.WriteLine("T1:{0}", i);
return i++;
}
public void T2(string s)
{
Console.WriteLine("T2:{0}", s);
}
}
我们继续写一点其它的例子,诸如拦截属性访问和异常。
Field Aspect
[Serializable]
public class AopPropertyAttribute : OnFieldAccessAspect
{
public override void OnGetValue(FieldAccessEventArgs eventArgs)
{
Console.WriteLine("ExposedFieldValue:{0}; StoredFieldValue:{1}",
eventArgs.ExposedFieldValue, eventArgs.StoredFieldValue);
}
public override void OnSetValue(FieldAccessEventArgs eventArgs)
{
Console.WriteLine("ExposedFieldValue:{0}; StoredFieldValue:{1}",
eventArgs.ExposedFieldValue, eventArgs.StoredFieldValue);
}
}
public class MyClass
{
[AopProperty]
private int x;
public int X
{
get { return x; }
set { x = value; }
}
}
Exception Aspect
[Serializable]
public class AopExceptionAttribute : OnExceptionAspect
{
public override void OnException(MethodExecutionEventArgs eventArgs)
{
Console.WriteLine(eventArgs.Exception.Message);
eventArgs.FlowBehavior = FlowBehavior.Return;
}
}
public class MyClass
{
[AopException]
public void Test(int i)
{
throw new Exception("Error");
}
}
更详细的信息,请访问 PostSharp 网站,或者查阅其帮助文件。
结论:
1.方法执行的日志记录可以用AOP实现
2.表之间的级联删除可以用AOP实现
3.数据库操作日志可以用AOP记录(因为数据库提供商不提供它的日志,导致第三方数据库同步无法便利实现)
...
由于采用 MSIL Injection,因此静态代码注入的执行效率要高于使用 Reflection Emit。
使用 MSBuild Task,使得开发人员可以像使用编译器内置 Attribute 那样使用 AOP。
可以拦截任意方法,而 Dynamic Proxy 方式的 AOP 往往采取继承方式来拦截 Virtual 方法。
拥有更多的控制权。包括中断执行流程,修改参数和返回值等等。
还可以拦截 Field Access、Exception 等操作。
无需将对象创建代码改成 "new proxy()",更加透明。
可以使用通配符进行多重拦截匹配。
静态注入带来的问题更多的是注入代码的质量和调试复杂度。
我们写一个简单的例子,看看效果。
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using PostSharp.Laos;
[Serializable]
public class AopMethodAttribute : OnMethodBoundaryAspect
public class MyClass
MyClass o = new MyClass();
o.Test(123);
输出:
OnEntry:MyClass.Int32 Test(Int32)
i=123
Test:123
OnExit...
整个过程非常简单:
1. 创建一个继承自 OnMethodBoundaryAspect 的特性类,用于拦截方法。
2. override 特定的方法,执行拦截操作。方法参数提供了各种操作能力。
3. 向目标方法添加特性。
4. 编译,执行。
或许你会好奇,AopMethodAttribute 是如何被创建实例,并被执行的呢?
1. 注意编译时 VS2005 Output 窗口的输出内容,你会看到如下内容。其实 PostSharp 提供了一个 MSBuild Task,在我们每次编译时会调用它执行一些注入操作。
PostSharp 1.0 [1.0.4.162] - Copyright (c) Gael Fraiteur and Community, 2006.
2. 用反编译工具看看注入后的方法内容。看完这些代码,就算我不说,你也能明白它是如何实现拦截的了。
static MyClass()
public int Test(int i)
我们可以使用通配符拦截更多的内容,以简化我们的编码。
[AopMethod(AttributeTargetMembers="T*")]
public class MyClass
{
public int T1(int i)
{
Console.WriteLine("T1:{0}", i);
return i++;
}
public void T2(string s)
{
Console.WriteLine("T2:{0}", s);
}
}
我们继续写一点其它的例子,诸如拦截属性访问和异常。
Field Aspect
[Serializable]
public class AopPropertyAttribute : OnFieldAccessAspect
{
public override void OnGetValue(FieldAccessEventArgs eventArgs)
{
Console.WriteLine("ExposedFieldValue:{0}; StoredFieldValue:{1}",
eventArgs.ExposedFieldValue, eventArgs.StoredFieldValue);
}
public override void OnSetValue(FieldAccessEventArgs eventArgs)
{
Console.WriteLine("ExposedFieldValue:{0}; StoredFieldValue:{1}",
eventArgs.ExposedFieldValue, eventArgs.StoredFieldValue);
}
}
public class MyClass
{
[AopProperty]
private int x;
public int X
{
get { return x; }
set { x = value; }
}
}
Exception Aspect
[Serializable]
public class AopExceptionAttribute : OnExceptionAspect
{
public override void OnException(MethodExecutionEventArgs eventArgs)
{
Console.WriteLine(eventArgs.Exception.Message);
eventArgs.FlowBehavior = FlowBehavior.Return;
}
}
public class MyClass
{
[AopException]
public void Test(int i)
{
throw new Exception("Error");
}
}
更详细的信息,请访问 PostSharp 网站,或者查阅其帮助文件。
结论:
1.方法执行的日志记录可以用AOP实现
2.表之间的级联删除可以用AOP实现
3.数据库操作日志可以用AOP记录(因为数据库提供商不提供它的日志,导致第三方数据库同步无法便利实现)
...
相关文章推荐
- PostSharp - 面向方面系统(转)
- Aop面向方面编程之PostSharp框架
- IoC容器与面向方面编程在SP无线运营系统设计中的应用
- C# Asp.net中的AOP框架 Microsoft.CCI, Mono.Cecil, Typemock Open-AOP API, PostSharp -摘自网络 (可以利用反射 Attribute 进行面向切面编程 可以用在记录整个方法的Log方面)
- 如果知道dll文件是面向32位系统还是面向64位系统的?
- 用PostSharp对.NET做死锁检测
- 企业商机舆情系统需要做什么方面
- PostSharp - Thread Dispatching(GUI多线程)
- 面向模式构建软件系统架构
- 基于面向对象思想利用Web Service开发三层体系结构的某市规划信息管理系统
- 面向对象编程(OOP)、面向组件编程(COP)、面向方面编程(AOP)和面向服务编程(SOP)
- 面向方面编程,有兴趣的一起学
- Operating Systems: Three Easy Pieces(操作系统:三个简单方面)5穿插章节:进程API/5.1系统调用:fork()
- PostSharp AOP编程:5.PostSharp的MethodInterceptionAspect类基本组成
- 中间件技术在系统设计规划方面的经验总结
- PostSharp AOP
- 代理模式、动态代理和面向方面
- 系统的横向结构和Websharp AOP
- AOP 面向方面编程的介绍----基本概念(2)
- 浅析Spring AOP(面向方面编程)