• .NET Core反射获取带有自定义特性的类,通过依赖注入根据Attribute元数据信息调用对应的方法


    前言

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

    C#中反射指的是什么?

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

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

    自定义一个Attribute类型

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

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

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

    注册需要注入的服务

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

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

    复制代码
        static void Main(string[] args)
        {
            var services = new ServiceCollection();
    
            //注册需要注入的服务
            services.AddTransient();
            services.AddTransient();
    
            var provider = services.BuildServiceProvider();
    
            #region 反射获取所有带有CustomAttribute特性的类并调用对应方法
    
            //反射获取所有带有CustomAttribute特性的类
            var classes = Assembly.GetExecutingAssembly().GetTypes()
                .Where(type => type.GetCustomAttributes().Any());
    
            foreach (var clazz in classes)
            {
                //获取标记CustomAttribute的实例
                var attr = clazz.GetCustomAttributes().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().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();
        }
    复制代码

    输出如下:

     

  • 相关阅读:
    GPU性能优化与模型训练概览
    C语言指针 动画展示 指针到底是什么 指针的本质 C语音深入剖析
    HarmonyOS/OpenHarmony原生应用-ArkTS万能卡片组件Slider
    如何使用MATLAB写测试(3)combinatorial explosion? 参数化!
    CCAA审核员职业健康安全管理体系基础考试大纲
    配置nginx域名转发
    每日一题:LeetCode-589.N叉树的前序遍历
    【【VDMA彩条显示实验之三 之 RGB LCD 彩条显示实验 】】
    Spring Boot Security自带功能齐全的HttpFirewall防火墙
    Spring官网下载各版本jar包
  • 原文地址:https://www.cnblogs.com/Can-daydayup/p/17320282.html