.NET Core中灵活使用反射

前言

前段时间有朋友问道一个这样的问题,.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);
                }
            }
        }

        #endregion

        Console.ReadLine();
    }

输出如下:

相关推荐

  1. Spring框架哪些地方使用反射

    2023-12-27 10:12:02       9 阅读
  2. 使用 PHP 的 Invoke 方法实现灵活而强大的调用

    2023-12-27 10:12:02       35 阅读
  3. <span style='color:red;'>反射</span>...

    反射...

    2023-12-27 10:12:02      7 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-27 10:12:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-27 10:12:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-27 10:12:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-27 10:12:02       18 阅读

热门阅读

  1. Spring Boot学习:Redis发布订阅

    2023-12-27 10:12:02       33 阅读
  2. SQL使用从入门到优化:目录

    2023-12-27 10:12:02       39 阅读
  3. Flink on K8S集群搭建及StreamPark平台安装

    2023-12-27 10:12:02       39 阅读
  4. Django、Python版本升级问题大汇总

    2023-12-27 10:12:02       40 阅读
  5. vue前端的ref()用法

    2023-12-27 10:12:02       36 阅读
  6. iOS获取手机型号(包含iOS15系列)

    2023-12-27 10:12:02       37 阅读
  7. 排序实训问答

    2023-12-27 10:12:02       36 阅读
  8. 博客搬家公告

    2023-12-27 10:12:02       42 阅读