(四)Apache log4net™ 手册 - AOP

0、引言

如果你已经开发了一个中型或者大型的 .NET / .NET Framework 项目但还没有为其添加日志系统。那么,你可能需要重新回顾大量的业务逻辑代码,并在其中找到合适的位置,编写合适的日志输出语句进行插入🙁。

显然,这是一个非常耗时且麻烦的工作,并且会对业务逻辑代码产生大量改动,造成代码的可读性变差。好在,我们可以利用面向切面编程(AOP)这一编程范式😀。在不修改现有代码的基础上,通过添加行为(Advice)来解决横切关注点;将通用功能(比如日志记录)从业务逻辑中抽离出来,使得我们能够专注于业务逻辑本身。

如果您不是很了解 AOP,那么以下的链接将会很有帮助:

  1. Aspect-oriented programming
  2. 细说Spring——AOP详解(AOP概览)
  3. Spring AOP(一) AOP基本概念
  4. 面向对象困境之 —— 横切关注点
  5. Aspect Oriented Programming
  6. What is Aspect-Oriented Programming (AOP)?
  7. AOP简单介绍

1、.NET 平台下的 AOP 实现

有非常多的编程语言都实现了 AOP,您可以在这里查看比较详细的列表。但我们的项目是基于 .NET / .NET Framework 的,使用的日志框架也是 log4net,所以我们重点关注 .NET 平台下的 AOP 框架:

名称logo描述
PostSharp.ilPOSTSHARP.ILPostSharp 旗下商业产品,一个基于 MSIL 的 .NET 下的面向切面框架,拥有功能受限的免费版本。
MetalamaMETALAMAPostSharp 旗下商业产品,一个 C# 中用于简洁代码的框架,拥有功能受限的免费版本。(MSDN 上提供了 Metalama 的教程)
Castle DynamicProxyDynamicProxy一个用于在运行时动态生成轻量级 .NET 代理的库。代理对象允许在不修改类代码的情况下拦截对对象成员的调用。类和接口都可以被代理,但是只有虚成员可以被拦截。许多其他框架(如 Spring.NET、AspectCore-Framework 等)都内部使用了 Castle DynamicProxy 来提供 AOP 功能。
Spring.NETSPRING.net一个全功能的 .NET 应用程序框架,不仅提供了依赖注入和面向切面编程(AOP),还提供了数据访问抽象、ASP.NET 集成等功能(更多详细介绍)。
AspectCore-FrameworkDynamicProxyAspectCore 是一个面向 .NET Core 和 .NET Framework 的基于 AOP 的跨平台框架。Core 支持切面拦截器、依赖注入集成、Web 应用程序、数据验证等。

以上都是最近仍有更新的项目;如果您想要了解还有哪些更多 .NET 平台下的 AOP 框架仍然是活跃的,可以参考如下回答:

  1. What is the best implementation for AOP in .Net?
  2. What Aspect-Oriented Programming (AOP) libraries for .NET are still actively developed?

2、实践

对于上面介绍的几个 .NET 平台下的 AOP 实现,笔者只用过 PostSharp.il(尽管它是一个商业产品)。一是其使用门槛不高,很容易上手;二是 PostSharp 还是提供了功能受限的免费版本 —— PostSharp [Essentials] 的,而且即便功能受限,完成日志记录这一简单需求还是绰绰有余的。

此外,PostSharp Technologies 为学生、教室、开源项目、MVP、博客作者、流媒体主播、用户组领导者以及黑客马拉松等提供了免费的 Metalama 和 PostSharp 许可证。如果您需要,完全可以在他们的官方网站上申请免费许可证,以体验完整版(PostSharp [Ultimate])的所有功能。

PostSharp [Ultimate] 包括以下所有单独的 PostSharp 产品:

  • PostSharp [Framework]:构建您自己的切面,并开始从您的 .NET 代码库中消除样板代码。
  • PostSharp [Logging]:在对源代码没有任何影响的情况下为您的 .NET 项目添加高度详细的日志记录。
  • PostSharp [MVVM]:消除 INotifyPropertyChanged 样板代码等。
  • PostSharp [Threading]:在 .NET 中编写可验证的线程安全代码,而不用绞尽脑汁。
  • PostSharp [Caching]:通过一个简单的自定义属性来提高您的 .NET 应用程序性能。

postsharp.il Products

到这里已经很明显了:如果我们只是想为现有的应用程序添加日志记录的功能。那么单独的 PostSharp [Logging] 产品就可以满足需求了。

以下是配置 PostSharp [Logging] 的简略步骤:

📌 为什么只有简略步骤?

因为所有步骤都非常简单,按照简略步骤中的外部链接提示操作即可。

  1. 首先创建一个简单的应用程序(比如:使用 .NET 创建 Windows 窗体应用)
  2. 有关如何开始使用 PostSharp.il 的介绍参考官方网站的 Get started 即可。
  3. 如何将 PostSharp [Logging] 添加到我们的代码库,参考官方文档的 Getting Started with PostSharp Logging 即可。
  4. 如何将 PostSharp [Logging] 连接到 log4net 目标日志框架,参考官方文档的 Writing PostSharp Logging events to log4Net 即可。
  5. 如何配置日志信息的详细程度,参考官方文档的 Adjusting Logging Verbosity 即可(可选步骤)。
  6. 下图展示了一个日志文件的生成位置及内容示例:
    生成的日志
  7. 完整源码请参考 WinFormsApp4DotNet

结果

最终我们(在对源代码没有任何影响的情况下)将日志记录添加到项目方法中。我们将获得程序执行的超详细日志,包括参数值和返回值。可以添加、删除或重命名方法或其参数;无需担心,日志条目将与每个更改保持同步。将日志记录添加到代码库并维护它成为一项非常简单的任务

📜 笔记
除了用于记录日志,面向切面编程(AOP)还有几种常见的应用场景:

  • 监控方法运行时间:通过 AOP 可以方便地统计方法的运行时间,从而进行性能分析;
  • 权限控制:通过 AOP 可以在方法执行前进行权限验证,从而实现统一的权限控制;
  • 缓存优化:例如,第一次调用查询数据库,将查询结果放入内存对象,第二次调用时,直接从内存对象返回,不需要查询数据库;
  • 事务处理:可以在方法执行前后进行事务的开启和提交,实现统一的事务管理;
  • 异常处理:可以在方法抛出异常后进行统一的异常处理;
  • 资源池管理:可以在方法执行前后进行资源的获取和释放,实现统一的资源管理;

总之,只要有大量重复的样板代码,或者有一些公共功能需要在多个地方使用,就可以考虑使用 AOP。

3、外部链接:

  • C#进阶系列——AOP?AOP!
  • 如何优雅地记录操作日志?
  • SpringBoot AOP 详解和多种使用场景
  • Spring AOP在项目中的典型应用场景

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/170330.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言 sizeof 函数内部进行计算

直接看代码 #include <stdio.h> int main() {int i 2;int j;j sizeof(i i);printf("i %d, j %d", i ,j);return 0; }执行结果&#xff1a; 可以看到 i的值一直是没有变的&#xff0c; j 是int类型下 sizeof占用的大小为 4个字节&#xff0c;不是i的 22…

#电子电器架构 —— 车载网关初入门

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 PS:小细节,本文字数7000+,详细描述了网关在车载框架中的具体性能设置。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 没有人关注你。也无需有人关注你。你必须承认自己的价值,你不能站在他…

php 数组基础/练习

数组 练习在最后 数组概述 概述与定义 数组中存储键值对 数组实际上是一个有序映射 key-value&#xff0c;可将其当成真正的数组、列表&#xff08;向量&#xff09;、散列表、字典、集合、栈、队列等 数组中的元素可以是任意类型的数据对象&#xff08;可以嵌套数组&#…

计算机网络_03_tcp/ip四层模型

文章目录 1.为什么会有tcp/ip?2.tcp/ip是什么?3.为什么会有tcp/ip四层模型?4.tcp/ip四层模型介绍 1.为什么会有tcp/ip? 早期的计算机(计算机网络没有出现之前)几乎都是各自为战, 各种操作系统厂家百花齐放, 市面上的大部分计算机使用的都是不同的操作系统, 为每个人提供定…

GoLong的学习之路(七)语法之slice(切片)

书接上回&#xff0c;上回书中写道&#xff1a;指针&#xff0c;并说明了基本引用类型分配内存new和特定情况下slice&#xff08;切片&#xff09;&#xff0c;map&#xff0c;channel等集合函数的内存分配make。这篇文章就开始说明&#xff0c;slice。 文章目录 slice&#xf…

ACM练习C++知识点笔记

1、字符和数字的转换 #include<iostream> using namespace std; int main(){int n 8 - 48;cout<<n<<endl;return 0; } 数字转字符串 #include <string> #include <sstream> #include <iostream> using namespace std; int main() {doubl…

MySQL2:MySQL中一条查询SQL是如何执行的?

MySQL2&#xff1a;MySQL中一条查询SQL是如何执行的&#xff1f; MySQL中一条查询SQL是如何执行的&#xff1f;1.连接怎么查看MySQL当前有多少个连接&#xff1f;思考&#xff1a;为什么连接数是查看线程&#xff1f;客户端的连接和服务端的线程有什么关系&#xff1f;MySQL参数…

Zabbix出现 404Not FoundThe requested URL /zabbix was not found on this server.

目录 一、问题&#xff1a; 二、原因&#xff1a; 三、解决方法&#xff1a; 一、问题&#xff1a; Not Found The requested URL /zabbix was not found on this server. 二、原因&#xff1a; 未找到 在此服务器上找不到请求的 URL /zabbix。 /etc/httpd/conf.d 目录…

Flutter笔记:图片的 precacheImage 函数

Flutter笔记 图片的 precacheImage 函数 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/134004572 【简…

【谢希尔 计算机网络】第4章 网络层

目录 网络层 网络层的几个重要概念 网络层提供的两种服务 网络层的两个层面 网际协议 IP 虚拟互连网络 IP 地址 IP 地址与 MAC 地址 地址解析协议 ARP IP 数据报的格式 IP 层转发分组的过程 基于终点的转发 最长前缀匹配 使用二叉线索查找转发 网际控制报文协议…

【Docker】联合探讨Docker:容器化技术的革命性应用

前言 Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 &#x1f4d5;作者简介&#xff1a;热…

【021】整理力学拉伸实验数据(复制、黏贴、计算)_#VBA

整理力学拉伸实验数据 1. 需求2. 实现流程2.1 流程图2.2 运行方法2.3 完整代码 1. 需求 2. 实现流程 2.1 流程图 流程如上&#xff0c;因测试得到多个数据表格&#xff0c;先将表格数据合并&#xff0c;并以文件名作为每个数据的代号。然后更换坐标轴&#xff0c;通过对文件名…

docker部署prometheus+grafana服务器监控(一)

docker-compose 部署prometheusgrafana Prometheus Prometheus 是有 SoundCloud 开发的开源监控系统和时序数据库&#xff0c;基于 Go 语言开发。通过基于 HTTP 的 pull 方式采集时序数据&#xff0c;通过服务发现或静态配置去获取要采集的目标服务器&#xff0c;支持多节点工…

Python —— UI自动化之使用JavaScript进行元素点亮、修改、点击元素

1、JavaScript点亮元素 在控制台通过JavaScript语言中对元素点亮效果如下&#xff1a; 将这个语句和UI自动化结合&#xff0c;代码如下&#xff1a; locator (By.ID,"kw") # 是元组类型 web_element WebDriverWait(driver,5,0.5).until(EC.visibility_of_eleme…

java类的动态加载

java类的动态加载 java动态加载的机制&#xff1a; ClassLoader->SecureClassloader–>URLClassLoader–>AppClassLoader loadClass–>findClass(重写方法)–>defineClass(从字节码加载类) 初始化的时候会加载静态代码块 实例化的时候会加载构造代码块、无参构…

【AGC】更新应用信息报未知错误解决方法

【问题描述】 最近有几个开发者遇到了一个问题&#xff0c;他们在AGC控制台配置好应用信息的图标和截图之后&#xff0c;点击保存按钮会弹出“未知错误&#xff0c;请稍后再试”的异常报错&#xff0c;导致无法正确保存应用配置信息。 出错页面如图所示。 ​​ 【解决方案】 …

怎么防止文件夹被删除、复制?

当文件夹中存放重要数据时&#xff0c;我们需要严格保护文件夹的安全&#xff0c;避免文件夹被复制、删除。那么&#xff0c;该怎么防止文件夹被删除、复制呢&#xff1f;下面我们就一起来了解一下。 ​文件夹隐藏 当文件夹被隐藏时&#xff0c;其他人无法发现文件夹&#xff…

STM32-LCD中英文显示及应用

目录 字符编码 ASCII码&#xff08;8位&#xff09; 中文编码&#xff08;16位&#xff09; GB2312标准 GBK编码 GB18030标准&#xff08;32位&#xff09; Big5编码 Unicode字符集和编码 UTF-32&#xff08;32位&#xff09; UTF-16&#xff08;16位/32位&#xff0…

桶装水订水送水小程序开发搭建;

上门送水小程序桶装水配送是一款的同城上门配送平台&#xff0c;为用户提供便捷的桶装水配送服务。解决用户在获取干净健康的饮用水方面的需求&#xff0c;提供高效、便捷的在线预约和下单服务。 小程序平台开发&#xff0c;具备强大的技术支持和良好的用户体验。用户可以通过…

【vue3】依赖注 provide、inject(父组件与儿子、孙子、曾孙子组件之间的传值)

一、基本用法&#xff1a; //父组件 import { ref, provide } from vue const radio ref<string>(red) provide(myColor,radio) //注入依赖//儿子组件、孙子组件、曾孙子组件 import { inject } from vue import type { Ref } from vue; const myColor inject<Ref&l…