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

.NET 6能否动态扫描后台服务并自动调用AddHostedService<T>注册?

解决.NET 6 Worker Service动态注册后台服务的问题

要解决动态注册同命名空间下非抽象Worker类的问题,核心是替换泛型版AddHostedService<T>的调用方式——因为泛型参数需要编译期确定的类型,而你通过反射获取的worker是运行时的Type实例,无法直接作为泛型参数使用。以下是两种可行方案:

方案一:使用非泛型版AddHostedService(推荐)

IServiceCollection提供了接受Type参数的非泛型扩展方法,直接传入反射获取的类型即可。同时建议优化类型筛选条件,确保只注册继承自BaseWorker的类,避免误注册同命名空间下的其他类:

var host = Host.CreateDefaultBuilder(args)
    .ConfigureServices(services =>
    {
        var baseWorkerNamespace = typeof(BaseWorker).Namespace;
        var workers = Assembly.GetExecutingAssembly().GetTypes()
            .Where(worker =>
                worker is { IsClass: true, IsAbstract: false } &&
                !string.IsNullOrWhiteSpace(worker.Namespace) &&
                worker.Namespace.Equals(baseWorkerNamespace) &&
                typeof(BaseWorker).IsAssignableFrom(worker)) // 确保继承自BaseWorker
            .ToArray();

        foreach (var worker in workers)
        {
            // 使用非泛型重载,直接传入Type实例
            services.AddHostedService(worker);
        }
    })
    .Build();

await host.RunAsync();

方案二:通过反射调用泛型版AddHostedService<T>

如果必须使用泛型方法,可以通过反射构造泛型版本并调用:

var host = Host.CreateDefaultBuilder(args)
    .ConfigureServices(services =>
    {
        var baseWorkerNamespace = typeof(BaseWorker).Namespace;
        var workers = Assembly.GetExecutingAssembly().GetTypes()
            .Where(worker =>
                worker is { IsClass: true, IsAbstract: false } &&
                !string.IsNullOrWhiteSpace(worker.Namespace) &&
                worker.Namespace.Equals(baseWorkerNamespace) &&
                typeof(BaseWorker).IsAssignableFrom(worker))
            .ToArray();

        // 获取泛型方法的定义
        var addHostedServiceMethod = typeof(ServiceCollectionHostedServiceExtensions)
            .GetMethod(nameof(ServiceCollectionHostedServiceExtensions.AddHostedService), 
                new[] { typeof(IServiceCollection) });

        foreach (var worker in workers)
        {
            // 构造对应类型的泛型方法并调用
            var genericMethod = addHostedServiceMethod.MakeGenericMethod(worker);
            genericMethod.Invoke(null, new object[] { services });
        }
    })
    .Build();

await host.RunAsync();

注意事项

  • 确保BaseWorker继承自BackgroundService或直接实现IHostedService,否则注册的类无法被识别为后台服务。
  • 若你的Worker类需要依赖注入,确保其构造函数符合依赖注入的要求(比如公开的构造函数,参数均已注册到服务容器)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 14:47:01