You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core通过程序集扫描实现Options模式配置注册的问题

解决.NET Core中通过程序集扫描自动注册配置的问题

完全可行,核心问题在于Configure<T>是泛型方法,泛型参数需要编译时确定,但你扫描得到的Type是运行时动态获取的,因此必须通过反射来调用泛型方法的实例。以下是完整的实现方案:

1. 调整自定义属性(可选,语义化命名)

把原有的TestAttribute改名为更贴合业务的名字,增强可读性:

[AttributeUsage(AttributeTargets.Class)]
public class ConfigSectionAttribute : Attribute
{
    public string SectionKey { get; }

    public ConfigSectionAttribute(string sectionKey)
    {
        SectionKey = sectionKey;
    }
}

2. 实现自动注册的扩展方法

修改你的扩展方法,通过反射调用Configure<T>泛型方法:

using System.Reflection;
using Microsoft.Extensions.DependencyInjection;

public static class WebApplicationBuilderConfigExtensions
{
    public static void RegisterConfig(this WebApplicationBuilder builder)
    {
        // 获取Configure<T>(IServiceCollection, IConfiguration)的方法定义
        var configureMethod = typeof(OptionsServiceCollectionExtensions)
            .GetMethod(
                nameof(OptionsServiceCollectionExtensions.Configure),
                new[] { typeof(IServiceCollection), typeof(IConfiguration) }
            ) ?? throw new InvalidOperationException("无法找到Configure方法重载");

        // 扫描所有带ConfigSectionAttribute的非抽象类
        var configTypes = AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(assembly => assembly.GetTypes())
            .Where(type => type is { IsClass: true, IsAbstract: false } 
                           && type.IsDefined(typeof(ConfigSectionAttribute), false));

        foreach (var type in configTypes)
        {
            var sectionAttr = type.GetCustomAttribute<ConfigSectionAttribute>();
            if (sectionAttr == null || string.IsNullOrWhiteSpace(sectionAttr.SectionKey))
                continue;

            // 获取配置节
            var configSection = builder.Configuration.GetSection(sectionAttr.SectionKey);
            if (!configSection.Exists())
                continue; // 可选:配置节不存在时跳过注册

            // 创建泛型方法实例并执行注册
            var genericConfigureMethod = configureMethod.MakeGenericMethod(type);
            genericConfigureMethod.Invoke(null, new object[] { builder.Services, configSection });
        }
    }
}

3. 使用方式

在Program.cs中直接调用扩展方法即可完成自动注册:

var builder = WebApplication.CreateBuilder(args);

// 一行代码完成所有配置类的注册
builder.RegisterConfig();

// 其他启动逻辑...
var app = builder.Build();

关键细节说明

  • 反射调用泛型方法时,必须先获取泛型方法定义,再通过MakeGenericType传入动态Type生成具体的方法实例
  • 添加了IsAbstract: false过滤,避免尝试对抽象类注册配置
  • 可选的配置节存在性检查,防止无效的空配置注册
  • 确保配置类是可实例化的具体类,符合Options模式的要求

内容的提问来源于stack exchange,提问作者Impostor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 00:10:58