最近,项目经理要求我做一个记录日志的功能,就是当系统的当前用户进行增删改或者上传文件操作的时候,进行对操作人,操作,操作时间的记录。他的建议是用特性去实现该功能。
经常有周边人问,Attribute是什么?它有什么用?好像没有这个东东程序也能运行。实际上在.Net中,Attribute是一个非常重要的组成部分,本文整理相关资料,提供给大家参考。
首先,我们肯定Attribute是一个类,下面是msdn文档对它的描述:公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型、字段、方法和属性等。
Attributes和Microsoft .NET Framework文件的元数据保存在一起,可以用来向运行时描述你的代码,或者在程序运行的时候影响应用程序的行为。
在.NET中,Attribute被用来处理多种问题,比如序列化、程序的安全特征、防止即时编译器对程序代码进行优化从而代码容易调试等等。
复杂的,面向组件的业务开发,期待现代的软件开发工程师们具备更多的弹性设计,而不是过去的方法设计。微软的.NET框架通过众所周知的声明式编程,广泛的使用特性来附加额外的功能。在软件系统里,使用特性可以增强系统的弹性,这是因为,特性使功能的低耦合得到了增强。所以,你可以定制自己的特性类,然后根据你自己的意图,合理的使用这些具有低耦合功效的特性。
使用.NET框架编写Windows程序,在很多方面已经变得很简单。在许多情况下,.NET框架使用.NET编译器,在编译时绑定到程序集的元数据,使灵活的程序设计变得更容易。事实上,对于.NET而言,使用内嵌的元数据把我们从DLL地狱解脱出来是可能的。
值得庆幸的是,.NET框架的设计者们并没有选择把这些元数据优雅的隐藏起来。设计者们把反射API给予了我们,通过反射,一个.NET程序可以通过编程查看这个元数据。一个程序可以反射出包含在特定程序集内任意的东西,或者说是包含在其内的所有的类型和成员。(反射内容待续,请关注)
把元数据绑定到可执行的程序集里,提供了许多优势。这使得.NET程序集,完全可以自我描述。还允许开发者跨语言共享组件,去除了头文件的需要。(这些头文件会由于相关的实现代码而过期。)
关于.NET元数据所有好的地方,看起来很难让人相信,它好像没什么用,仅仅是个谎言。但是,它确实是存在的。在.NET里,你可以创建自己特定程序的元数据,并且可以把这些元数据应用到你可以想象到的地方。
开发者通过使用自定义特性,可以定义他们自己特定程序的元数据。因为这些特性的值将变成另一部分元数据,绑定到一个程序集里。所以这些自定义特性的值可以被反射API检查到并且可以被使用。
首先,我们先定义一个特性类,这个特性类继承于Attribute,再在它的构造函数里面实现记录日志的方法
public class LogAttribute:Attribute { /// <summary> /// 特性构造函数 /// </summary> /// <param name="operate">操作</param> /// <param name="operateTime">操作时间</param> public LogAttribute(string operate,DateTime operateTime) { LogAccess access = new LogAccess(); string loginName = GetCurrentUserName();//当前登录用户 access.Log(loginName, operate, operateTime); } }
然后,我们在要实现记录日志功能的方法头上加入该特性,并传入正确的参数
/// <summary> /// 新增 /// </summary> /// <returns></returns> [LogAttribute("新增了一条数据",DateTime.Now)] public ActionResult AddArchivesFile(string ArchivesID, string ProjectCode) { InsertArchivesFileModel model = new InsertArchivesFileModel(); model.ArchivesID = ArchivesID; ViewBag.ProjectCode = ProjectCode; ViewBag.StageList = getStage(); ViewBag.FileSeq = getFileSeq(ArchivesID); return View(model); }
这样,在新增数据之前,就对操作人,操作,操作时间进行了记录,但是有个麻烦的地方就是要在每一个需要记录的方法前面都加入该特性。