PostSharp是基于.NET平台设计的比较强调易学易用的AOP框架,AOP的概念,优点请参见:
http://www.cnblogs.com/wayfarer/category/35983.html 这里只是简要的介绍几种使用PostSharp实现的场景供大家参考。 一、日志 一般我们写入业务方面的日志有两种方式, 1、简单的记录业务方法的发生时间,触发用户,业务方法名等 传统方案我们是这样记录的。 public class Employee { public void Add( string employeeName, string employeePwd) { Console.WriteLine( " 添加员工名:{0},密码:{1} " ,employeeName,employeePwd); LogManager.LogWrite( " Add " ); } } class LogManager { public static void LogWrite( string methodName) { GenericPrincipal gp = (GenericPrincipal)Thread.GetData( Thread.GetNamedDataSlot( " Principal " )); Console.WriteLine( " 用户名:{0},日志时间:{1},触发此日志的方法:{2} " , gp.Identity.Name, DateTime.Now.ToString(), methodName); } } // 主程序: static void Main( string [] args) { GenericIdentity gi = new GenericIdentity( " lfm " ); GenericPrincipal gp = new GenericPrincipal(gi, new string [] { " Admin " }); LocalDataStoreSlot localSlot = Thread.AllocateNamedDataSlot( " Principal " ); Thread.SetData(localSlot, gp); Employee em = new Employee(); em.Add( " lfm " , " lfm " ); }
(因为这里使用的控制台应用程序,为了便于测试我们使用了线程槽来存储用户,如果不理解这个部分可以暂时忽略用户信息。)传统方案的日志记录的问题是每个需要记录日志的方法都要依赖于LogManager类,也就是说所有的业务逻辑都要依赖于系统级的LogManager类,我们能不能让他们彻底的分离开呢,下面我们使用PostSharp提供的方式来解决这个问题。
要使用PostSharp必须先下载()PostSharp,安装之后需要至少引入PostSharp.Laos,PostSharp.Public两个程序集。PostSharp是利用特性(Attribute)将业务类和系统类联系在一起的,所以我们需要首先定义SampleLogAttribute类如下: 使用postSharp记录日志 [Serializable] class SampleLogAttribute : OnMethodBoundaryAspect { public override void OnSuccess(MethodExecutionEventArgs eventArgs) { LogManager.LogWrite(eventArgs); } } 日志记录类: class LogManager { public static void LogWrite(MethodExecutionEventArgs eventArgs) { GenericPrincipal gp = (GenericPrincipal)Thread.GetData( Thread.GetNamedDataSlot( " Principal " )); Console.WriteLine( " 用户名:{0},日志时间:{1},触发此日志的方法:{2} " , gp.Identity.Name, DateTime.Now.ToString(), eventArgs.Instance.ToString() + " . " + eventArgs.Method.Name); } }
然后在需要记录日志的方法上标识SampleLogAttribute即可
相应方法 [SampleLog] public void Add( string employeeID, string pwd) { Console.WriteLine( " 用户名:{0}密码:{1} " , employeeID, pwd); }
这时我们运行程序会得到如下结果:
这里我们需要去了解一下OnMethodBoundaryAspect类,我们可以通过重写OnEntry,OnSuccess两个方法来截获方法的信息,OnEntry是在标识了相应特性的方法前触发,而OnSuccess是在标识了相应特性的方法后触发。
2、我们可能需要记录方法的一些更详细的信息,比如说更新操作,我们需要记录更新前的信息 日志的记录特性代码如下: 复杂日志记录 [Serializable] class UpdateLogAttribute : OnMethodBoundaryAspect { public override void OnEntry(MethodExecutionEventArgs eventArgs) { LogManager.LogWrite(eventArgs); foreach (var item in eventArgs.Instance.GetType().GetProperties()) { Console.WriteLine( " 原属性名:{0},原值:{1} " ,item.Name, item.GetValue(eventArgs.Instance, null )); } Console.WriteLine(); } } // 业务类: class Employee { public Employee( string employeeID, string pwd) { this .EmployeeID = employeeID; this .Pwd = pwd; } [UpdateLog] public void Update(Employee em) { this .EmployeeID = em.EmployeeID; this .Pwd = em.Pwd; Console.WriteLine( " 更新后:employeeID:{0},pwd:{1} " , this .EmployeeID, this .Pwd); } public string EmployeeID { get ; set ; } public string Pwd { get ; set ; } }
运行主程序结果如下:
也许还有些情况日志记录会更复杂,但一般情况下我们都可以通过截获方法的参数,实例的属性等获得想要的信息。可能你会觉得这样一个一个写特性也挺麻烦,PostSharp提供了一种广播横切点的方式,我们可以在类上使用相关的特性然后设置其AttributeTargetMembers值,如:
[SampleLog(AttributeTargetMembers = "Add*")] class Employee { } 这样Employee类中所有使用Add开头的方法都将记录日志,也可以设定整个程序集,大家可以参考PostSharp提供的文档。 本文转自 你听海是不是在笑 博客园博客,原文链接: http://www.cnblogs.com/nuaalfm/archive/2009/02/23/1396415.html ,如需转载请自行联系原作者