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

相关文章

C#下Newtonsoft.Json的具体使用

《C#下Newtonsoft.Json的具体使用》Newtonsoft.Json是一个非常流行的C#JSON序列化和反序列化库,它可以方便地将C#对象转换为JSON格式,或者将JSON数据解析为C#对... 目录安装 Newtonsoft.json基本用法1. 序列化 C# 对象为 JSON2. 反序列化

QT Creator配置Kit的实现示例

《QTCreator配置Kit的实现示例》本文主要介绍了使用Qt5.12.12与VS2022时,因MSVC编译器版本不匹配及WindowsSDK缺失导致配置错误的问题解决,感兴趣的可以了解一下... 目录0、背景:qt5.12.12+vs2022一、症状:二、原因:(可以跳过,直奔后面的解决方法)三、解决方

MySQL中On duplicate key update的实现示例

《MySQL中Onduplicatekeyupdate的实现示例》ONDUPLICATEKEYUPDATE是一种MySQL的语法,它在插入新数据时,如果遇到唯一键冲突,则会执行更新操作,而不是抛... 目录1/ ON DUPLICATE KEY UPDATE的简介2/ ON DUPLICATE KEY UP

Python中Json和其他类型相互转换的实现示例

《Python中Json和其他类型相互转换的实现示例》本文介绍了在Python中使用json模块实现json数据与dict、object之间的高效转换,包括loads(),load(),dumps()... 项目中经常会用到json格式转为object对象、dict字典格式等。在此做个记录,方便后续用到该方

JWT + 拦截器实现无状态登录系统

《JWT+拦截器实现无状态登录系统》JWT(JSONWebToken)提供了一种无状态的解决方案:用户登录后,服务器返回一个Token,后续请求携带该Token即可完成身份验证,无需服务器存储会话... 目录✅ 引言 一、JWT 是什么? 二、技术选型 三、项目结构 四、核心代码实现4.1 添加依赖(pom

SpringBoot路径映射配置的实现步骤

《SpringBoot路径映射配置的实现步骤》本文介绍了如何在SpringBoot项目中配置路径映射,使得除static目录外的资源可被访问,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一... 目录SpringBoot路径映射补:springboot 配置虚拟路径映射 @RequestMapp

Python与MySQL实现数据库实时同步的详细步骤

《Python与MySQL实现数据库实时同步的详细步骤》在日常开发中,数据同步是一项常见的需求,本篇文章将使用Python和MySQL来实现数据库实时同步,我们将围绕数据变更捕获、数据处理和数据写入这... 目录前言摘要概述:数据同步方案1. 基本思路2. mysql Binlog 简介实现步骤与代码示例1

C#文件复制异常:"未能找到文件"的解决方案与预防措施

《C#文件复制异常:未能找到文件的解决方案与预防措施》在C#开发中,文件操作是基础中的基础,但有时最基础的File.Copy()方法也会抛出令人困惑的异常,当targetFilePath设置为D:2... 目录一个看似简单的文件操作问题问题重现与错误分析错误代码示例错误信息根本原因分析全面解决方案1. 确保

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的

基于C#实现PDF转图片的详细教程

《基于C#实现PDF转图片的详细教程》在数字化办公场景中,PDF文件的可视化处理需求日益增长,本文将围绕Spire.PDFfor.NET这一工具,详解如何通过C#将PDF转换为JPG、PNG等主流图片... 目录引言一、组件部署二、快速入门:PDF 转图片的核心 C# 代码三、分辨率设置 - 清晰度的决定因