前言

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

C#中反射指的是什么?

开篇之前首先和大家简单介绍一下反射的概念和作用。

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

自定义一个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);
}
}
} #endregion Console.ReadLine();
}

输出如下:

最新文章

  1. 理解nodejs模块的scope
  2. bzoj1800[Ahoi2009]fly 飞行棋 暴力枚举
  3. EPSON LQ610K 设置税控盘打印发票的格式
  4. 自学XSL的几个例子
  5. Idea调试显示切换数据源的设置
  6. ubuntu 修复 could not open file &#39;/etc/apt/sources.list&#39;
  7. java Queue中 add/offer,element/peek,remove/poll区别
  8. 17Linux_mariadb_PXE+Kickstart
  9. [转] Meida视频加密二-Blob对象
  10. Python+Selenium学习--自动化测试模型
  11. CentOS7下用firewall-cmd控制端口与端口转发
  12. JS 引擎执行机制
  13. 记录一次nginx配置vhost的小bug
  14. [UOJ#245][UER#7]天路(近似算法)
  15. HTML表格相关元素
  16. DbUtils(一) 结果集概览
  17. Bank Simulation Program银行管理系统C++ :)
  18. 洛谷P1220 关路灯(区间dp)
  19. sqlit中使用到的查询语句
  20. Promise嵌套问题/async await执行顺序

热门文章

  1. OSIDP-文件管理-12(end)
  2. Crypto入门 (五)混合编码
  3. JS数组创建
  4. java比较器:Comparable和Comparator
  5. 记一次Centos7上安装VNC服务
  6. DNS CNAME limitations cname 在哪些情况下不能配置
  7. django+ajax实现xlsx文件下载功能
  8. 远程链接linux编程shell脚本
  9. Android工程接入UnityLibrary工程
  10. LoadRunner——安装教程以及创建与录制(一)