ASP.NET Core 2.0使用Autofac注入Controller

时间:2017-12-12 17:07:31

标签: c# autofac asp.net-core-2.0

我正在尝试用Autofac注入我的控制器。不幸的是,我无法在远处配置Autofac,因此'DefaultControllerActivator`不会构建我的控制器?

    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().AddControllersAsServices();
        var containerBuilder = new ContainerBuilder();
        containerBuilder.RegisterModule<ServiceModule>();
        containerBuilder.Populate(services);
        containerBuilder.RegisterType<LoginController>().PropertiesAutowired();

        ApplicationContainer = containerBuilder.Build();
        return new AutofacServiceProvider(this.ApplicationContainer);
    }

    public class ServiceModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            builder.RegisterModule(new DataProviderModule());
            builder.RegisterType(typeof(LoginService)).As(typeof(ILoginService)).InstancePerRequest();
        }
    }

    [Route("api/[controller]")]
    public class LoginController : Controller
    {
        private readonly ILoginService _loginService;

        public LoginController(ILoginService loginService)
        {
            _loginService = loginService;
        }
    }

我按照上面显示的Autofac文档进行操作。不幸的是,不会构造LoginController,因为它需要注入。

编辑:如果有一种方法可以使用没有Autofac的“模块”,我会对任何建议都非常有趣:)

提前谢谢你!

2 个答案:

答案 0 :(得分:4)

在ASP.NET Core中使用InstancePerLifetimeScopedifferences between ASP.NET and ASP.NET Core like this are documented

答案 1 :(得分:4)

默认情况下,ASP.NET Core将从容器中解析控制器参数,但实际上并不从容器中解析控制器。这通常不是问题,但确实意味着:

控制器的生命周期由框架处理,而不是请求生命周期。

控制器构造函数参数的生命周期由请求生存期处理。 在注册控制器期间可能进行的特殊接线(如设置属性注入)将无效。

当您使用服务集合注册MVC时,可以通过指定AddControllersAsServices()来更改此设置。当您调用builder.Populate(services)时,这样做会自动将控制器类型注册到IServiceCollection中。

public class Startup
{
  public IContainer ApplicationContainer {get; private set;}
  public IServiceProvider ConfigureServices(IServiceCollection services)
  {
    // Add controllers as services so they'll be resolved.
    services.AddMvc().AddControllersAsServices();

    var builder = new ContainerBuilder();

    // When you do service population, it will include your controller
    // types automatically.
    builder.Populate(services);

    // If you want to set up a controller for, say, property injection
    // you can override the controller registration after populating services.
    builder.RegisterType<MyController>().PropertiesAutowired();

    this.ApplicationContainer = builder.Build();
    return new AutofacServiceProvider(this.ApplicationContainer);
  }
}