首页 > 解决方案 > 使用 Autofac 4.2.1 注入已注册的命名服务未按预期工作

问题描述

背景

Autofac 4.2.1(尝试使用最新版本的 Autofac 并且问题仍然存在),WebApi 项目 .netcore 2.2 问题:我有两个相同服务的实例,我注册到 ContainerBuilder 的名称为:

builder.RegisterType<ServiceOne>().Named<IService>("ServiceOne").SingleInstance();
builder.RegisterType<ServiceTwo>().Named<IService>("ServiceTwo").SingleInstance();

然后我根据需要将命名服务注入我的控制器类:

builder.Register(c => new KeysController(c.ResolveNamed<IService>("ServiceOne")));
builder.Register(c => new ValuesController(c.ResolveNamed<IService>("ServiceTwo")));

Autofac 无法按名称解析我的两个控制器的 IService。

例外

处理请求时发生未处理的异常。InvalidOperationException:尝试激活“AutoFacNaming.Controllers.ValuesController”时无法解析“AutoFacNaming.IService”类型的服务。

标签: c#exceptiondependency-injection.net-coreautofac

解决方案


默认情况下,ASP.net 核心不会从容器构建控制器,而只会构建它的参数。您可以通过指定AddControllersAsServices()何时向服务集合注册 MVC 来更改此设置。这样做会IServiceCollection在服务提供者工厂调用时自动将控制器类型注册到builder.Populate(services).

public class Startup
{
  // Omitting extra stuff so you can see the important part...
  public void ConfigureServices(IServiceCollection services)
  {
    // Add controllers as services so they'll be resolved.
    services.AddMvc().AddControllersAsServices();
  }

  public void ConfigureContainer(ContainerBuilder builder)
  {
    // If you want to set up a controller for, say, property injection
    // you can override the controller registration after populating services.
    builder.Register(c => new KeysController(c.ResolveNamed<IService>("ServiceOne")));
    builder.Register(c => new ValuesController(c.ResolveNamed<IService>("ServiceTwo")));
  }
}

您可以在Autofac 文档中了解更多信息


推荐阅读