Search code examples
c#.netasp.net-core.net-coreautofac

Using autofac in asp.net core 2.2


I am trying to use latest Autofac with asp.net core 2.2 project. However documentation of autofac seems to be outdated. I am trying to use autofac without ConfigureContainer:

// ConfigureServices is where you register dependencies. This gets
  // called by the runtime before the Configure method, below.
  public IServiceProvider ConfigureServices(IServiceCollection services)
  {
    // Add services to the collection.
    services.AddMvc();

    // Create the container builder.
    var builder = new ContainerBuilder();

    // Register dependencies, populate the services from
    // the collection, and build the container.
    //
    // Note that Populate is basically a foreach to add things
    // into Autofac that are in the collection. If you register
    // things in Autofac BEFORE Populate then the stuff in the
    // ServiceCollection can override those things; if you register
    // AFTER Populate those registrations can override things
    // in the ServiceCollection. Mix and match as needed.
    builder.Populate(services);
    builder.RegisterType<MyType>().As<IMyType>();
    this.ApplicationContainer = builder.Build();

    // Create the IServiceProvider based on the container.
    return new AutofacServiceProvider(this.ApplicationContainer);
  }

but the ConfigureServices method signature is different in asp.net core 2.2

public void ConfigureServices(IServiceCollection services)
{
}

there is not return type. Anyone knows how to use autofac in asp.net core 2.2?


Solution

  • You need to use this package:

    Autofac.Extensions.DependencyInjection

    In your program.cs, just use these lines of code:

        public static IWebHostBuilder CreateWebHostBuilder(string[] args)
        {
            return WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .ConfigureServices(services => services.AddAutofac());
        }
    

    In your startup.cs, create a method called

        public void ConfigureContainer(ContainerBuilder builder)
        {
        }
    

    And use "builder" to register whatever you want. Autofac will find this method itself.

    You don't need to call any builder.Build() anymore.

    Following remarks in order to execute reccurent code with injected values, you need to add:

    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddHostedService<MyHostedService>();
        ...
    }
    
    public class MyHostedService : IHostedService
    {
        private Timer _timer;
        private IInjectedService _myInjectedService;
    
        public MyHostedService(IServiceProvider services)
        {
            var scope = services.CreateScope();
    
            _myInjectedService = scope.ServiceProvider.GetRequiredService<IInjectedService>();
        }
    
        public Task StartAsync(CancellationToken cancellationToken)
        {
            _timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromMinutes(5));
    
            return Task.CompletedTask;
        }
    
        public Task StopAsync(CancellationToken cancellationToken)
        {
            _timer?.Change(Timeout.Infinite, 0);
    
            return Task.CompletedTask;
        }
    
        private async void DoWork(object state)
        {
            _myInjectedService.DoStuff();
        }
    }