如果你已经开发了一个中型或者大型的 .NET / .NET Framework 项目但还没有为其添加日志系统。那么,你可能需要重新回顾大量的业务逻辑代码,并在其中找到合适的位置,编写合适的日志输出语句进行插入🙁。
显然,这是一个非常耗时且麻烦的工作,并且会对业务逻辑代码产生大量改动,造成代码的可读性变差。好在,我们可以利用面向切面编程(AOP)这一编程范式😀。在不修改现有代码的基础上,通过添加行为(Advice
)来解决横切关注点;将通用功能(比如日志记录)从业务逻辑中抽离出来,使得我们能够专注于业务逻辑本身。
如果您不是很了解 AOP,那么以下的链接将会很有帮助:
有非常多的编程语言都实现了 AOP,您可以在这里查看比较详细的列表。但我们的项目是基于 .NET / .NET Framework 的,使用的日志框架也是 log4net,所以我们重点关注 .NET 平台下的 AOP 框架:
名称 | logo | 描述 |
---|---|---|
PostSharp.il | PostSharp 旗下商业产品,一个基于 MSIL 的 .NET 下的面向切面框架,拥有功能受限的免费版本。 | |
Metalama | PostSharp 旗下商业产品,一个 C# 中用于简洁代码的框架,拥有功能受限的免费版本。(MSDN 上提供了 Metalama 的教程) | |
Castle DynamicProxy | 一个用于在运行时动态生成轻量级 .NET 代理的库。代理对象允许在不修改类代码的情况下拦截对对象成员的调用。类和接口都可以被代理,但是只有虚成员可以被拦截。许多其他框架(如 Spring.NET、AspectCore-Framework 等)都内部使用了 Castle DynamicProxy 来提供 AOP 功能。 | |
Spring.NET | 一个全功能的 .NET 应用程序框架,不仅提供了依赖注入和面向切面编程(AOP),还提供了数据访问抽象、ASP.NET 集成等功能(更多详细介绍)。 | |
AspectCore-Framework | AspectCore 是一个面向 .NET Core 和 .NET Framework 的基于 AOP 的跨平台框架。Core 支持切面拦截器、依赖注入集成、Web 应用程序、数据验证等。 |
以上都是最近仍有更新的项目;如果您想要了解还有哪些更多 .NET 平台下的 AOP 框架仍然是活跃的,可以参考如下回答:
对于上面介绍的几个 .NET 平台下的 AOP 实现,笔者只用过 PostSharp.il(尽管它是一个商业产品)。一是其使用门槛不高,很容易上手;二是 PostSharp 还是提供了功能受限的免费版本 —— PostSharp [Essentials] 的,而且即便功能受限,完成日志记录这一简单需求还是绰绰有余的。
此外,PostSharp Technologies 为学生、教室、开源项目、MVP、博客作者、流媒体主播、用户组领导者以及黑客马拉松等提供了免费的 Metalama 和 PostSharp 许可证。如果您需要,完全可以在他们的官方网站上申请免费许可证,以体验完整版(PostSharp [Ultimate])的所有功能。
PostSharp [Ultimate] 包括以下所有单独的 PostSharp 产品:
INotifyPropertyChanged
样板代码等。到这里已经很明显了:如果我们只是想为现有的应用程序添加日志记录的功能。那么单独的 PostSharp [Logging] 产品就可以满足需求了。
📌 为什么只有简略步骤?
因为所有步骤都非常简单,按照简略步骤中的外部链接提示操作即可。
WinFormsApp4DotNet
。最终我们(在对源代码没有任何影响的情况下)将日志记录添加到项目方法中。我们将获得程序执行的超详细日志,包括参数值和返回值。可以添加、删除或重命名方法或其参数;无需担心,日志条目将与每个更改保持同步。将日志记录添加到代码库并维护它成为一项非常简单的任务。
📜 笔记
除了用于记录日志,面向切面编程(AOP)还有几种常见的应用场景:
- 监控方法运行时间:通过 AOP 可以方便地统计方法的运行时间,从而进行性能分析;
- 权限控制:通过 AOP 可以在方法执行前进行权限验证,从而实现统一的权限控制;
- 缓存优化:例如,第一次调用查询数据库,将查询结果放入内存对象,第二次调用时,直接从内存对象返回,不需要查询数据库;
- 事务处理:可以在方法执行前后进行事务的开启和提交,实现统一的事务管理;
- 异常处理:可以在方法抛出异常后进行统一的异常处理;
- 资源池管理:可以在方法执行前后进行资源的获取和释放,实现统一的资源管理;
- …
总之,只要有大量重复的样板代码,或者有一些公共功能需要在多个地方使用,就可以考虑使用 AOP。