近几天接触 PostSharp, 看看别人写的挺简单的,遂决定试一下(先前看过 Castle ,可它的动态代理好像只能在 virtual 方法上,不知道是我理解错了还是..否则就是 要用上 ioc....放弃).
就我所理解的,选用 PostSharp 的好处有:
1.采用 MSIL 静态代码注入,避免使用反射;
2.使用 MSBuild Task,使得开发人员可以像使用编译器内置 Attribute 那样使用 AOP;
3.可以拦截任意方法而不是局限于 virtual 方法;
4.对调用方法有更多的控制方法,比如输入参数,返回结果等
话会正题.开始前先到官网下载一个版本的 PostSharp(www.postsharp.org). 现在已经出了2.0 了,不过是45天的试用期,(过期收费?).装上试一下,它会在 vs2008 上面安插一个插件(这个暂不理会).真正到项目中使用的还是免费的好(我自己怎么为公司掏?),还是下个 1.5 的吧,关闭 vs 后安装.
新建一个 console 项目. 先模拟实现 Log:
日志模拟记录
public
static
class
Log
{
public static void Write(MethodExecutionEventArgs eventArgs, string message)
{
Console.WriteLine( " 开始日志记录.方法名: {0} , 实例名: {1}. 附带信息:{2} " ,
eventArgs.Method.Name, eventArgs.Instance , message );
}
}
{
public static void Write(MethodExecutionEventArgs eventArgs, string message)
{
Console.WriteLine( " 开始日志记录.方法名: {0} , 实例名: {1}. 附带信息:{2} " ,
eventArgs.Method.Name, eventArgs.Instance , message );
}
}
引用postsharp相关dll后(1.5: postsharp.laos ,postsharp.public .2.0 就 postsharp ) 再实现某个类型的 attribute : 继承自 AttributeTargets (1.5 的namespace 是 PostSharp.public ,2.0 好像 PostSharp.Aspects )
注意:1.5和 2.0 方法签名不一样
[Serializable]
[ global ::System.AttributeUsage(AttributeTargets.All, AllowMultiple = true )]
public class PostsAttribute : OnMethodBoundaryAspect
{
/* PostSharp 2.0 里可用的方法
public override void OnSuccess(MethodExecutionArgs args)
{
Console.WriteLine("...{0}...onsuccess......", DateTime.Now);
base.OnSuccess(args);
Log.Write(args);
}
*/
private string _msg = string .Empty;
public PostsAttribute( string message) {
_msg = message;
}
public override void OnEntry(MethodExecutionEventArgs args)
{
Console.WriteLine( " ...{0}...onEntry...... " , DateTime.Now);
base .OnEntry(args);
}
public override void OnExit(MethodExecutionEventArgs args)
{
Console.WriteLine( " ...{0}...OnExit...... " , DateTime.Now);
base .OnExit(args);
}
}
[ global ::System.AttributeUsage(AttributeTargets.All, AllowMultiple = true )]
public class PostsAttribute : OnMethodBoundaryAspect
{
/* PostSharp 2.0 里可用的方法
public override void OnSuccess(MethodExecutionArgs args)
{
Console.WriteLine("...{0}...onsuccess......", DateTime.Now);
base.OnSuccess(args);
Log.Write(args);
}
*/
private string _msg = string .Empty;
public PostsAttribute( string message) {
_msg = message;
}
public override void OnEntry(MethodExecutionEventArgs args)
{
Console.WriteLine( " ...{0}...onEntry...... " , DateTime.Now);
base .OnEntry(args);
}
public override void OnExit(MethodExecutionEventArgs args)
{
Console.WriteLine( " ...{0}...OnExit...... " , DateTime.Now);
base .OnExit(args);
}
}
准备就绪后使用:
如何调用:
class
Start
{
static void Main() {
Speak( " 我开始哈 " );
EndSpeak();
Console.ReadKey();
}
[Posts( " 开始说话了.. " )]
private static void Speak( string message) {
Console.WriteLine( " .{0}.....正式执行了.... " , message);
}
[Posts( " error: " )]
[onException( " endspeak " )]
static void EndSpeak() {
Console.WriteLine( " 会发生错误的调用...... " );
throw new Exception( " ====== 这是故意发生的错误.=== " );
}
}
{
static void Main() {
Speak( " 我开始哈 " );
EndSpeak();
Console.ReadKey();
}
[Posts( " 开始说话了.. " )]
private static void Speak( string message) {
Console.WriteLine( " .{0}.....正式执行了.... " , message);
}
[Posts( " error: " )]
[onException( " endspeak " )]
static void EndSpeak() {
Console.WriteLine( " 会发生错误的调用...... " );
throw new Exception( " ====== 这是故意发生的错误.=== " );
}
}
运行结果:
完整的 test 见源文件: 下载
安装文件下载: /Files/infozero/PostSharp安装文件.rar