如何在 Autofac 模块的依赖注入中注入 IHostedService

How to Inject IHostedService in Dependecy injection from Autofac Module

我正在尝试使用 Autofac Di 容器而不是 .netcore default IServiceCollection 来构建依赖项。我需要注入 IHostedServiceIServiceCollection 有方法 AddHostedService 但我在 Autofac ContainerBuilder 中找不到替代方法。

Autofac 文档说您可以从 IServiceCollection 填充 ContainerBuilder 因此一种解决方案是在 IServiceCollection 中添加 IHostedService 然后从中填充 ContainerBuilder 但我有多个 AutofacModule,其中一些注册每个其他,他们每个人都对自己的服务负责,直接在 Startup 中从 ChildModule 注入一些服务似乎不对。

 public class ParentModule : Module
 {
    protected override void Load(ContainerBuilder builder)
    {
       builder.RegisterModule(new ChildModule());
    }
 }

 public class ChildModule : Module
 {
    protected override void Load(ContainerBuilder builder)
    {
       //TODO Add hosted service here.
    }
 }

 public class Startup
 {
   ...
   ...
   public IServiceProvider ConfigureServices(IServiceCollection services)
   {
      var container = new ContainerBuilder();
      container.RegisterModule(new ParentModule());

      return new AutofacServiceProvider(container.Build());
   }
   ...
   ...
 }

最终我想将 ParentModule 打包并上传到自定义 NugetServer 中,这样我就可以在需要的任何地方添加 ParentModule,而无需记住在 IServiceCollection 中注入一些服务。

我的模块非常复杂并且在多层次深度上,因此 IServiceCollection 添加额外依赖项的简单扩展方法不是一个选项。

像这样注册他们

builder.RegisterType<MyHostedService>()
       .As<IHostedService>()
       .InstancePerDependency();

主机(web-host 或常规主机)负责解析 IHostedService 的所有注册并运行它们。

如您所见,扩展方法AddHostedService<THostedService>没有做任何不同

public static IServiceCollection AddHostedService<THostedService>(this IServiceCollection services)
where THostedService : class, IHostedService
{
   return services.AddTransient<IHostedService, THostedService>();
}

您可以在 github 上找到 source-code。

更新 2022-03-15

正如评论中所指出的,MS注册现在使用的是单例。虽然在技术上对于这种特定情况并不重要,但如果您想使其与 MS 注册保持一致,则需要执行以下操作

builder.RegisterType<MyHostedService>()
       .As<IHostedService>()
       .SingleInstance();