37

I am trying to add Autofac to a .Net 6.0 web API. I'm using the latest ASP.NET Core Web API template that generates a single start-up Program.cs file.

Installed Autofac versions:

Autofac 6.3.0
Autofac.Extensions.DependancyInjection (7.2.0-preview.1)

Installed .Net 6.0 versions:

Microsoft.AspNetCore.App 6.0.0-rc.2.21480.10
Microsoft.NETCore.App 6.0.0-rc.2.21480.5
Microsoft.WindowsDesktop.App 6.0.0-rc.2.21501.6

Just in case of doubt, this is the entire content of the Program.cs file (yes, no namespaces or class definition. Only a Program.cs file and no StartUp class or Startup.cs file)

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run()

I've tried looking through the latest Autofac documentation but the examples there, despite saying for .Net Core 3.x and later don't seem to fit with .Net 6.0 code. I can't figure out how to add Autofac into the middleware pipeline.

Any help is greatly appreciated.

Code snippet from Autofac website

public class Program
{
  public static void Main(string[] args)
  {
    // ASP.NET Core 3.0+:
    // The UseServiceProviderFactory call attaches the
    // Autofac provider to the generic hosting mechanism.
    var host = Host.CreateDefaultBuilder(args)
        .UseServiceProviderFactory(new AutofacServiceProviderFactory())
        .ConfigureWebHostDefaults(webHostBuilder => {
          webHostBuilder
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>();
        })
        .Build();

    host.Run();
  }
}

Autofac documention:

https://docs.autofac.org/en/latest/integration/aspnetcore.html#asp-net-core-3-0-and-generic-hosting

Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
github-user-202
  • 371
  • 1
  • 3
  • 5
  • 1
    [Please don't double post](https://github.com/autofac/Autofac.Extensions.DependencyInjection/issues/97) - the Autofac folks monitor StackOverflow, too. In the future, just post questions here and if we can answer them, we will. – Travis Illig Oct 29 '21 at 13:29

4 Answers4

57

I found this Microsoft docs

var builder = WebApplication.CreateBuilder(args);

builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());

// Register services directly with Autofac here.
// Don't call builder.Populate(), that happens in AutofacServiceProviderFactory.
builder.Host.ConfigureContainer<ContainerBuilder>(
   builder => builder.RegisterModule(new MyApplicationModule()));

var app = builder.Build();
Hakan Fıstık
  • 16,800
  • 14
  • 110
  • 131
David Kuchař
  • 571
  • 2
  • 3
  • 2
    the ConfigureContainer is generic and should reference the AutoFac ContainerBuilder type, like so: builder.Host.ConfigureContainer(containerBuilder => { containerBuilder.RegisterModule(new EmptyModule()); }); – HenningK Nov 14 '21 at 23:42
  • 9
    For copy-pasters like me: You also need to add Autofac.Extensions.DependencyInjection package, not only Autofac. – Petr Feb 05 '22 at 07:30
  • I don't know if any of you had the same issue, in ConfigureContainer, Visual Studio tells me that it contains the Configuration Property however when I want to use it, it gives me an error saying I cannot access it.. Anyone else had that issue? Also, I can't seem to have any way of passing IConfiguration if I want to read from the appsettings.json file to then define Settings I want to register as IOption. – tessierp Feb 18 '22 at 17:49
  • @tessierp you can access `IConfiguration` through `builder.Configuration`. – thinkOfaNumber Jul 15 '22 at 05:49
  • @tessierp to use settings in your modules I suggest to use dependency injection and [options pattern](https://learn.microsoft.com/en-us/dotnet/core/extensions/options) provided by .NET. In this way you register a configuration with `services.Configure` and inject `IOptions` in constructor of the module (or any other service). – Roberto Ferraris May 11 '23 at 15:09
18

At "Program.cs"

You'll find

var builder = WebApplication.CreateBuilder(args);

Add below

builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory())
    .ConfigureContainer<ContainerBuilder>(builder =>
    {
        builder.RegisterModule(new AutofacBusinessModule());
    });

Answer above, I've assumed that you had everything else set up. I'm using Autofac and Autofact.Extras.DynamicProxy

Sharing below my AutofacBusinessModule just for clarification.

public class AutofacBusinessModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            builder.RegisterType<ProductManager>().As<IProductService>().SingleInstance();
            builder.RegisterType<EfProductDal>().As<IProductDal>().SingleInstance();
        }
    }
Hakan Fıstık
  • 16,800
  • 14
  • 110
  • 131
SoupriceCoder
  • 226
  • 2
  • 7
9

I have attached examples of both manual declarations and Reflection API of how to add Autofac to .NET Core 6.0

  1. Call UseServiceProviderFactory on the Host sub-property
  2. Call ConfigureContainer on the Host sub-property
  3. Declare your services and their lifetime

Example of a manual services declaration

var builder = WebApplication.CreateBuilder(args);

// Call UseServiceProviderFactory on the Host sub property 
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());

// Call ConfigureContainer on the Host sub property 
builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
{
   // Declare your services with proper lifetime

    builder.RegisterType<AppLogger>().As<IAppLogger>().SingleInstance();
    builder.RegisterType<DataAccess>().As<IDataAccess>().InstancePerLifetimeScope();

});

Example of Assembly scanning "Reflection API"

var builder = WebApplication.CreateBuilder(args);

// Call UseServiceProviderFactory on the Host sub property 
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());

// Call ConfigureContainer on the Host sub property 
builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
{
 builder.RegisterAssemblyTypes(Assembly.Load(nameof(DemoLibrary))).Where(t => t.Namespace?.Contains("Practicing.Services") == true)
    .As(t => t.GetInterfaces().FirstOrDefault(i => i.Name == "I" + t.Name));

});
Obaida Alhassan
  • 516
  • 1
  • 5
  • 12
0

You can add all types with this.

builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());

var assembly = System.Reflection.Assembly.GetExecutingAssembly();

builder.Host.ConfigureContainer<ContainerBuilder>(builder => builder.RegisterAssemblyModules(assembly));
Fehmi Aksakal
  • 31
  • 1
  • 7