Nieksa
Nieksa

Reputation: 374

ASP.NET Core 2.0 inject Controller with Autofac

I'm trying to inject my controller with Autofac. Unfortunately I am unable to configure Autofac in away so that the 'DefaultControllerActivator` wont construct my controllers?

    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;
        }
    }

I followed the documentation of Autofac as shown above. Unfortunately the LoginController will not be constructed because it requires an injection.

edit: If there is a way of using "Modules" without Autofac, I'd be very interesting for any suggestions :)

Thanks you in advance!

Upvotes: 3

Views: 17426

Answers (2)

Pepito Fernandez
Pepito Fernandez

Reputation: 2440

By default, ASP.NET Core will resolve the controller parameters from the container but doesn’t actually resolve the controller from the container. This usually isn’t an issue but it does mean:

The lifecycle of the controller is handled by the framework, not the request lifetime.

The lifecycle of controller constructor parameters is handled by the request lifetime. Special wiring that you may have done during registration of the controller (like setting up property injection) won’t work.

You can change this by specifying AddControllersAsServices() when you register MVC with the service collection. Doing that will automatically register controller types into the IServiceCollection when you call builder.Populate(services).

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);
  }
}

Upvotes: 5

Travis Illig
Travis Illig

Reputation: 23924

Use InstancePerLifetimeScope in ASP.NET Core. The differences between ASP.NET and ASP.NET Core like this are documented.

Upvotes: 4

Related Questions