C# DotNetCore AOP简单实现

2023-12-18 06:04

本文主要是介绍C# DotNetCore AOP简单实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景

实际开发中业务和日志尽量不要相互干扰嵌套,否则很难维护和调试。

示例

using System.Reflection;namespace CSharpLearn
{internal class Program{static void Main(){int age = 25;string name = "bingling";Person person = new(age, name);Console.WriteLine("====================不使用AOP====================");person.DisplayMessage();Console.WriteLine();person.DisplayMessage("name");Console.WriteLine("====================不使用AOP====================");Console.WriteLine();/*============================代理对象============================*/PersonProxyDynamic<Person> personProxyDynamic = new();personProxyDynamic.Before += (methodInfo) =>{List<string> pt = new();foreach (ParameterInfo? parameterInfo in methodInfo.GetParameters()){if (parameterInfo.ParameterType.FullName != null){pt.Add(parameterInfo.ParameterType.FullName);}}Console.WriteLine($"准备执行{methodInfo.Name}({string.Join(",", pt)})");};personProxyDynamic.After += (methodInfo) =>{Console.WriteLine($"执行{methodInfo.Name}完毕");};/*============================代理对象============================*/Console.WriteLine("====================使用了AOP====================");personProxyDynamic.Excute(person, "DisplayMessage", new object[] { "name" });Console.WriteLine();personProxyDynamic.Excute(person, "DisplayMessage", null);Console.WriteLine();personProxyDynamic.Excute(person, "DisplayMessage", new object[] { 123 });Console.WriteLine();Console.WriteLine("====================使用了AOP====================");}}/// <summary>/// 人物类/// </summary>public class Person{/// <summary>/// 姓名/// </summary>private readonly string name;/// <summary>/// 年龄/// </summary>private readonly int age;public Person(int age, string name){this.age = age;this.name = name;}/// <summary>/// 打印姓名和年龄/// </summary>public void DisplayMessage(){Console.WriteLine($"{{'age':{age},'name':'{name}'}}");}/// <summary>/// 根据需要打印姓名或年龄/// </summary>/// <param name="type">传入name或age</param>public void DisplayMessage(string type){switch (type){case "name":Console.WriteLine($"{{'name':'{name}'}}");break;case "age":Console.WriteLine($"{{'age':'{age}'}}");break;}}}/// <summary>/// 代理类/// </summary>/// <typeparam name="T">泛型T</typeparam>public class PersonProxyDynamic<T>{/// <summary>/// 执行方法前/// </summary>public Action<MethodInfo>? Before { get; set; }/// <summary>/// 执行方法后/// </summary>public Action<MethodInfo>? After { set; get; }/// <summary>/// 代理执行某个对象的某个方法/// </summary>/// <param name="t">被代理的对象</param>/// <param name="method">被执行的方法</param>/// <param name="args">被执行方法的参数列表</param>public void Excute(T t, string method, params object[]? args){//获取被代理对象的所有名字为传入method的方法MethodInfo[]? methodInfos = typeof(T).GetMethods().Where(item => item.Name == method).ToArray();//没有此名字的方法if (methodInfos == null || methodInfos.Length == 0 || methodInfos.FirstOrDefault(item => item == null) != null){Console.WriteLine($"{t}对象没有{method}方法");return;}//存在此名字的方法,注意区分是否为重载的方法foreach (MethodInfo methodInfo in methodInfos){//方法传参列表是否和args每个元素的类型一一对应bool flag = true;//无参方法,传入null或长度为0的参数列表都可以if (methodInfo.GetParameters().Length == 0 && (args == null || args.Length == 0)){}//有参方法,两者传参长度需要一致、且传入的参数类型等于方法的参数类型或者隶属于其子类else if (methodInfo.GetParameters().Length == args?.Length){for (int i = 0; i < methodInfo.GetParameters().Length; i++){Type type1 = methodInfo.GetParameters()[i].ParameterType;Type type2 = args[i].GetType();//参数列表类型不一致,且传入的参数类型不隶属于签名的参数类型if (type1 != type2 && !type2.IsSubclassOf(type1)){flag = false;break;}}}//有参方法,长度不一致else{flag = false;}//命中用户想调用的方法if (flag){Before?.Invoke(methodInfo);methodInfo.Invoke(t, args);After?.Invoke(methodInfo);return;}}Console.WriteLine("未找到您要调用的方法");}}
}

 运行结果

解析

业务中有一个Person类,其业务为调用Person实例的DisplayMessage方法打印该person对象的个人信息。

PersonProxyDynamic类为其动态代理类,我们在给其对象添加前置后置处理函数后,即可对person对象的所有方法进行代理,这样我们就可以在原本使用person对象方法的地方,替换成动态代理类的Execute方法,保证的原有的person代码不变,业务逻辑干净纯粹。

此示例仅供参考,由于使用了反射,生产环境若是对性能具备高要求,切勿轻易使用!!!

这篇关于C# DotNetCore AOP简单实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/507295

相关文章

基于Python实现一个图片拆分工具

《基于Python实现一个图片拆分工具》这篇文章主要为大家详细介绍了如何基于Python实现一个图片拆分工具,可以根据需要的行数和列数进行拆分,感兴趣的小伙伴可以跟随小编一起学习一下... 简单介绍先自己选择输入的图片,默认是输出到项目文件夹中,可以自己选择其他的文件夹,选择需要拆分的行数和列数,可以通过

Python中将嵌套列表扁平化的多种实现方法

《Python中将嵌套列表扁平化的多种实现方法》在Python编程中,我们常常会遇到需要将嵌套列表(即列表中包含列表)转换为一个一维的扁平列表的需求,本文将给大家介绍了多种实现这一目标的方法,需要的朋... 目录python中将嵌套列表扁平化的方法技术背景实现步骤1. 使用嵌套列表推导式2. 使用itert

C#读写文本文件的多种方式详解

《C#读写文本文件的多种方式详解》这篇文章主要为大家详细介绍了C#中各种常用的文件读写方式,包括文本文件,二进制文件、CSV文件、JSON文件等,有需要的小伙伴可以参考一下... 目录一、文本文件读写1. 使用 File 类的静态方法2. 使用 StreamReader 和 StreamWriter二、二进

Python使用pip工具实现包自动更新的多种方法

《Python使用pip工具实现包自动更新的多种方法》本文深入探讨了使用Python的pip工具实现包自动更新的各种方法和技术,我们将从基础概念开始,逐步介绍手动更新方法、自动化脚本编写、结合CI/C... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

在Linux中改变echo输出颜色的实现方法

《在Linux中改变echo输出颜色的实现方法》在Linux系统的命令行环境下,为了使输出信息更加清晰、突出,便于用户快速识别和区分不同类型的信息,常常需要改变echo命令的输出颜色,所以本文给大家介... 目python录在linux中改变echo输出颜色的方法技术背景实现步骤使用ANSI转义码使用tpu

C#中Guid类使用小结

《C#中Guid类使用小结》本文主要介绍了C#中Guid类用于生成和操作128位的唯一标识符,用于数据库主键及分布式系统,支持通过NewGuid、Parse等方法生成,感兴趣的可以了解一下... 目录前言一、什么是 Guid二、生成 Guid1. 使用 Guid.NewGuid() 方法2. 从字符串创建

Python使用python-can实现合并BLF文件

《Python使用python-can实现合并BLF文件》python-can库是Python生态中专注于CAN总线通信与数据处理的强大工具,本文将使用python-can为BLF文件合并提供高效灵活... 目录一、python-can 库:CAN 数据处理的利器二、BLF 文件合并核心代码解析1. 基础合

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文

golang版本升级如何实现

《golang版本升级如何实现》:本文主要介绍golang版本升级如何实现问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录golanwww.chinasem.cng版本升级linux上golang版本升级删除golang旧版本安装golang最新版本总结gola

SpringBoot中SM2公钥加密、私钥解密的实现示例详解

《SpringBoot中SM2公钥加密、私钥解密的实现示例详解》本文介绍了如何在SpringBoot项目中实现SM2公钥加密和私钥解密的功能,通过使用Hutool库和BouncyCastle依赖,简化... 目录一、前言1、加密信息(示例)2、加密结果(示例)二、实现代码1、yml文件配置2、创建SM2工具