.NET Core中灵活使用反射

news/2024/4/19 1:13:51

前言

前段时间有朋友问道一个这样的问题,.NET Core中如何通过Attribute的元数据信息来调用标记的对应方法。我第一时间想到的就是通过C#反射获取带有Custom Attribute标记的类,然后通过依赖注入(DI)的方式获取对应服务的方法并通过反射动态执行类的方法,从而实现更灵活的编程方式。

什么是反射?

在 C# 中,反射是指在运行时动态地获取类型的信息并操作对象的能力。使用反射,我们可以在代码中访问程序集、模块、成员等,并且可以操作这些成员的属性、方法、字段和事件等。

反射的作用

  1. 动态加载程序集。

  2. 获取类型信息。

  3. 创建对象和调用方法。

  4. 访问和操作成员。

  5. 扩展框架和库。

注意:由于反射是一种非常灵活和强大的机制,但也带来了一定的性能开销。因此,在使用反射时应慎重考虑其适用性,并权衡性能和灵活性的取舍。

自定义一个Attribute类型

/// <summary>
/// 自定义一个Attribute类型
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class CustomAttribute : Attribute
{public string TargetMethod { get; set; }public CustomAttribute(string targetMethod){TargetMethod = targetMethod;}
}

定义如下两个需要被执行的服务,并使用CustomAttribute标记

/// <summary>
/// 前进服务
/// </summary>
[Custom("AdvanceWay")]
public class AdvanceService
{public void AdvanceWay(){Console.WriteLine("On the move!");}
}/// <summary>
/// 后退服务
/// </summary>
[Custom("RetreatWay")]
public class RetreatService
{public void RetreatWay(){Console.WriteLine("Be retreating!");}
}

注册需要注入的服务

var services = new ServiceCollection();//注册需要注入的服务
services.AddTransient<AdvanceService>();
services.AddTransient<RetreatService>();

反射获取所有带有CustomAttribute特性的类并调用对应方法

static void Main(string[] args){var services = new ServiceCollection();//注册需要注入的服务services.AddTransient<AdvanceService>();services.AddTransient<RetreatService>();var provider = services.BuildServiceProvider();#region 反射获取所有带有CustomAttribute特性的类并调用对应方法//反射获取所有带有CustomAttribute特性的类var classes = Assembly.GetExecutingAssembly().GetTypes().Where(type => type.GetCustomAttributes<CustomAttribute>().Any());foreach (var clazz in classes){//获取标记CustomAttribute的实例var attr = clazz.GetCustomAttributes<CustomAttribute>().First();//根据CustomAttribute元数据信息调用对应的方法var methodInfo = clazz.GetMethod(attr.TargetMethod);if (methodInfo != null){//instance 对象是通过依赖注入容器获取的。这是一种常用的实现方式,可以使用依赖注入解耦程序中各个组件之间的依赖关系,方便测试和维护。var instance = provider.GetService(clazz);methodInfo.Invoke(instance, null);}}#endregion#region 反射获取所有带有CustomAttribute特性的类并调用指定方法var executionMethod = "RetreatWay";foreach (var clazz in classes){//获取标记CustomAttribute的实例var attr = clazz.GetCustomAttributes<CustomAttribute>().First();if (attr.TargetMethod == executionMethod){//根据CustomAttribute元数据信息调用对应的方法var methodInfo = clazz.GetMethod(attr.TargetMethod);if (methodInfo != null){//instance 对象是通过依赖注入容器获取的。这是一种常用的实现方式,可以使用依赖注入解耦程序中各个组件之间的依赖关系,方便测试和维护。var instance = provider.GetService(clazz);methodInfo.Invoke(instance, null);}}}#endregionConsole.ReadLine();}

输出如下:


http://www.ppmy.cn/news/1281992.html

相关文章

6.3 多线程的安全与应用

6.3 多线程的安全与应用 1. 多线程概念1. 进程2. 线程 2. 创建多线程3. 线程同步4. 线程安全5. 线程池应用 1. 多线程概念 1. 进程 2. 线程 2. 创建多线程 3. 线程同步 4. 线程安全 5. 线程池应用

边缘计算云边端全览—边缘计算系统设计与实践【文末送书-10】

文章目录 一.边缘计算1.1边缘计算的典型应用 二.边缘计算 VS 云计算三.边缘计算系统设计与实践【文末送书-10】3.1 粉丝福利&#xff1a;文末推荐与福利免费包邮送书&#xff01; 一.边缘计算 边缘计算是指在靠近物或数据源头的一侧&#xff0c;采用网络、计算、存储、应用核心…

Windows操作系统:共享文件夹,防火墙的设置

1.共享文件夹 1.1 共享文件夹的优点 1.2 共享文件夹的优缺点 1.3 实例操作 ​编辑 2.防火墙设置 2.1 8080端口设置 3.思维导图 1.共享文件夹 1.1 共享文件夹的优点 优点 协作和团队合作&#xff1a;共享文件夹使多个用户能够在同一文件夹中协作和编辑文件。这促进了团…

掌握这3分钟自我介绍,你的软件测试面试就稳了

自我介绍在面试中常常作为第一个问题而出现&#xff0c;好的自我介绍可以带来良好的第一印象&#xff0c;如何讲好自我介绍呢。我建议从三部分下手 一、个人的基本信息&#xff0c;扬长避短 1、年纪太大与太小&#xff0c;都不需要主动去说明。 比如我年纪只有21岁 例子&am…

免费高清无水印视频素材在哪里下?

剪辑是一门创意工作&#xff0c;但很多初学者常常感到困惑&#xff0c;原因并不是因为他们不懂剪辑&#xff0c;而是因为他们不知道从哪里找到合适的素材。今天&#xff0c;我们将为大家盘点一些超全的剪辑素材资源&#xff0c;包括视频素材、音乐素材和图片素材等&#xff0c;…

关于:网络安全

网络安全是指保护网络系统及其相关设备免受未经授权访问、使用、破坏、更改、泄露和破坏的活动的过程。随着互联网的迅速发展&#xff0c;网络安全问题也越来越突出&#xff0c;已成为全球范围内的一个重要议题。本文将详细探讨网络安全的定义、重要性、常见威胁、防御措施和未…

云卷云舒:云原生业务应用成熟度模型

笔者最近学习了信通院发布的《云原生应用成熟度的评估模型》&#xff0c;做如下解读&#xff1a; 一、概述 云原生业务应用成熟度模型从企业业务应用基础设施域、应用研发域以及服务治理域等三个能力域二十个过程域综合评估企业业务应用在弹性、高可用、自愈性、可观测性以及…

centos mysql8 设置远程访问

参考&#xff1a; https://blog.csdn.net/qq_15585305/article/details/129889474 # 先确保自己有授权权限 mysql> GRANT ALL PRIVILEGES ON *.* TO rootlocalhost WITH GRANT OPTION; Query OK, 0 rows affected (0.00 sec) # 更新一下权限 mysql> flush privileges; Q…

前端---表单标签

1. 表单的介绍 表单用于搜集不同类型的用户输入(用户输入的数据)&#xff0c;然后可以把用户数据提交到web服务器 。 2. 表单相关标签的使用 <form>标签 表示表单标签&#xff0c;定义整体的表单区域 <label>标签 表示表单元素的文字标注标签&#xff0c;定义文字…

轻量级开源服务器Tomcat本地部署并将网页发布到公网远程访问

目录 1.前言 2.本地Tomcat网页搭建 2.1 Tomcat安装 2.2 配置环境变量 2.3 环境配置 2.4 Tomcat运行测试 2.5 Cpolar安装和注册 3.本地网页发布 3.1.Cpolar云端设置 3.2 Cpolar本地设置 4.公网访问测试 5.结语 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通…

vue3整合Element-Plus,极速上手。

条件分页查询&#xff1a; 需求分析&#xff1a; form表单 Button按钮 Table表格 Pagination分页 页面布局&#xff1a; 搜索表单&#xff1a; 如果表单封装的数据较多&#xff0c;建议绑定到一个对象中。 …

微服务概念

1.什么是微服务&#xff1f; 顾名思义&#xff0c;是一个微小的服务&#xff0c;为什么会说是“ 微 ” 呢&#xff1f; 意思整个服务的是比较微小的&#xff0c;是一个独立的业务模块&#xff0c;专做改业务的事情&#xff0c;是一个独立的功能单元。 一种独特的架构设计模式&…

C# 虚拟按键和模拟鼠标

我们测试软件功能&#xff0c;有时候需要不停操作按键和鼠标。通过虚拟按键和模拟鼠标操作可以轻松完成重复而繁琐的操作&#xff0c;节省人工时间和人为失误。虚拟按键和模拟鼠标操作还可以实现对远程电脑的按键和鼠标操作&#xff0c;实现屏幕协助。 虚拟按键可通过Keybd_ev…

Unity VR Pico apk安装失败:INSTALL_FAILED_UPDATE_INCOMPATIBLE

我的报错&#xff1a; PICO4企业版。安装apk&#xff0c;报错“安装失败。&#xff08;所属的Unity项目打包的apk&#xff0c;被我在同一台pico4安装了20次&#xff09; 调试方法&#xff1a; PIco4发布使用UNITY开发的Vr应用&#xff0c;格式为apk&#xff0c;安装的时候发生…

termux_ubuntu 系统配置

1、添加新用户 由于 termux/ubuntu 默认创建和登录的是 root 用户&#xff0c;root 用户的 home 目录在 /root 下&#xff0c;这个使用起来很不方便&#xff0c;使用 root 用户也不太习惯&#xff0c;有必要创建新用户 # 创建新用户 useradd -d /home/new_user_name -m new_u…

使用 pytest.ini 文件控制输出 log 日志

一、前置说明 pytest.ini 文件中可以配置参数来控制 pytest 的运行行为,其存放路径要求与 conftest.py 一样。 项目根目录project_root/ ├── pytest.ini ├── tests/ │ └── test_demo.py以test开头的测试子目录project_root/ ├── tests/ │ ├── pytest.in…

引用jquery.js的html5基础页面模板

本专栏是汇集了一些HTML常常被遗忘的知识&#xff0c;这里算是温故而知新&#xff0c;往往这些零碎的知识点&#xff0c;在你开发中能起到炸惊效果。我们每个人都没有过目不忘&#xff0c;过久不忘的本事&#xff0c;就让这一点点知识慢慢渗透你的脑海。 本专栏的风格是力求简洁…

2023年12月25日学习总结——MLP

&#x1f4a1;我准备每一天都写一个学习总结&#xff0c;周末再把每日的学习总结汇总成专门的文章 &#x1f506;我的学习总结主要是为了自己的个人学习&#xff0c;没有商业用途&#xff0c;侵删 okkk开始今日学习 目录 1、今日计划学习内容2、今日学习内容深入学习MLP&#…

【力扣题解】P145-二叉树的后序遍历-Java题解

&#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【力扣题解】 文章目录 【力扣题解】P145-二叉树的后序遍历-Java题解&#x1f30f;题目描述&#x1f4a1;题解&#x1f30…

云原生周刊:Karmada 成为 CNCF 孵化项目 | 2023.12.25

开源项目推荐 kubernetes-reflector Reflector 是一个 Kubernetes 的插件&#xff0c;旨在监视资源&#xff08;secrets 和 configmaps&#xff09;的变化&#xff0c;并将这些变化反映到同一命名空间或其他命名空间中的镜像资源中。 Lingo Lingo 是适用于 K8s 的 OpenAI 兼…