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

.NET 5.0如何通过反射批量注册所有Hosted Service托管服务

实现方案

你可以直接通过反射筛选所有符合条件的Worker服务类型,手动注册为IHostedService单例即可,无需反射调用扩展方法,实现逻辑如下:

private static void RegisterHostedServices(IServiceCollection services)
{
    // 定位Worker服务所在的程序集,可根据你的实际项目结构调整为其他定位方式
    var assembly = Assembly.GetAssembly(typeof(BaseWorkerService<>));
    
    // 筛选所有非抽象、非接口、继承自BaseWorkerService的实现类
    var workerTypes = assembly.GetTypes()
        .Where(t => 
            !t.IsAbstract 
            && !t.IsInterface 
            && t.BaseType != null 
            && t.BaseType.IsGenericType 
            && t.BaseType.GetGenericTypeDefinition() == typeof(BaseWorkerService<>)
        );

    // 批量注册,等效于手动调用AddHostedService<T>
    foreach (var workerType in workerTypes)
    {
        services.TryAddEnumerable(ServiceDescriptor.Singleton(typeof(IHostedService), workerType));
    }
}

补充说明

  • 如果你更习惯通过反射调用AddHostedService扩展方法,可替换上述循环部分的逻辑:
// 获取AddHostedService泛型方法定义
var addHostedMethod = typeof(ServiceCollectionHostedServiceExtensions)
    .GetMethods(BindingFlags.Public | BindingFlags.Static)
    .First(m => 
        m.Name == nameof(ServiceCollectionHostedServiceExtensions.AddHostedService) 
        && m.GetParameters().Length == 1
    );

foreach (var workerType in workerTypes)
{
    // 构造对应泛型方法并执行
    var genericMethod = addHostedMethod.MakeGenericMethod(workerType);
    genericMethod.Invoke(null, new object[] { services });
}
  • 筛选条件可根据你的需求调整,比如你也可以通过是否实现IAppHostedService接口来筛选,写法如下:
var workerTypes = assembly.GetTypes()
    .Where(t => 
        !t.IsAbstract 
        && !t.IsInterface 
        && t.GetInterfaces().Contains(typeof(IAppHostedService))
    );
  • 如果你的Worker服务分布在多个程序集中,遍历所有相关程序集执行筛选逻辑即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 07:06:06