博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
实例讲解PostSharp(一)
阅读量:5986 次
发布时间:2019-06-20

本文共 3376 字,大约阅读时间需要 11 分钟。

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
,如需转载请自行联系原作者
你可能感兴趣的文章
各种经典布局--“国”字布局
查看>>
jboss启动报错
查看>>
程序员究竟该如何提高效率
查看>>
转面试题:跑灯
查看>>
spring mvc 单元测试
查看>>
swift与Objective-C的互用性
查看>>
Linux 进程管理
查看>>
Linux 线程相关函数理解
查看>>
我的友情链接
查看>>
2.3.1.shell awk 入门
查看>>
snmp在网络中的应用
查看>>
git 使用过程中问题记录
查看>>
SDN in Action: Deploy VXLAN with MP-BGP EV_P_N
查看>>
Maven学习总结(八)——使用Maven构建多模块项目
查看>>
Docker镜像与容器命令
查看>>
Java培训-日期类
查看>>
项目范围管理论文提纲
查看>>
python给qq发邮件
查看>>
关于mysql的 qps tps
查看>>
bootstrap datetimepicker 添加清空按钮
查看>>