Autofac In ASP NET Core - How To Avoid This Debugging Nightmare

Even though we get access to IServiceCollection when building .NET web apps, I still want more. One of the very first things that I do is integrate Autofac in ASP NET Core applications because of the capabilities and APIs of Autofac. The built-in dependency injection support has come a long way, so I don't mean to discredit it, but I do still prefer to leverage Autofac.

But there's a problem -- and that very well might be why you ended up at this article in the first place. Setting up Autofac in ASP NET Core is easy but it's also easy to mess up. I seemingly do this on every ASP NET Core project that I start, and I feel like enough is enough. The next time I go to search for how to solve this problem, I'm going to come across my OWN article and have the "Aha!" moment.

So let's see just how easy it is to get Autofac in ASP NET Core.


What's In This Article: Autofac in ASP NET Core

Remember to check out these other platforms:

// FIXME: social media icons coming back soon!


Example ASP NET Core Project

To walk through how to configure Autofac in ASP NET Core, I wanted to get us on the same page for a set of code. What better way than to use the built-in weather app project with minimal APIs?! I know that it's not that exciting, but it'll be much more exciting once you have it working with Autofac.

Let's have a look at the code first, paying attention to the TODO that's mentioned:

using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Mvc;
using System.Reflection;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
// ... TODO: this is where we need to hook up our dependencies!!

var app = builder.Build();

// Configure the HTTP request pipeline.
app.UseHttpsRedirection();

app.MapGet("/weatherforecast", (MyDependency myDependency) =>
{
    var summaries = myDependency.GetSummaries();
    var forecast = Enumerable.Range(1, 5).Select(index =>
        new WeatherForecast
        (
            DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            Random.Shared.Next(-20, 55),
            summaries[Random.Shared.Next(summaries.Count)]
        ))
        .ToArray();
    return forecast;
});

app.Run();

internal record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}

public sealed class MyDependency
{
    public IReadOnlyList<string> GetSummaries()
    {
        var summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };
        return summaries;
    }
}

This program is almost identical to the sample weather app, but I pulled the "summaries" array into a dedicated class called MyDependency. Not for any good reason except for us to have a class to inject, and we'll do so by providing it right on the minimal API definition itself.

Next, we'll need to make sure we get the NuGet package, so make sure you get the Autofac.Extensions.DependencyInjection package. This will by default include Autofac itself, but you'll need this NuGet package to interface with the IServiceCollection -- a key part of how we make this all work together!


The Wrong Way to Set Up Autofac in ASP NET Core

This is an obligatory part of the article even though I know you came here looking for a solution. I need to include this because I know there are other people out there searching for this, and even if there aren't, I know that I will be guaranteed to search for this in the future. I'd be happy to come across my own article with the example code telling me what's wrong! I was passionate enough about this problem that I even put this video together about this exact problem and how to set up Autofac in ASP NET Core the *right* way:

The problem stems from two main points:

  • The Autofac devs have left a method in place that shouldn't be used anymore (very likely for compatibility purposes)
  • ... I apparently can't seem to read or remember, no matter how many times I do this

And I'd like to take full responsibility. So let's check out this code snippet that shows what looks like the obvious way to hook things up:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddAutofac(containerBuilder =>
{
    containerBuilder.RegisterType<MyDependency>().SingleInstance();
});

We add the lovely extension method onto our IServiceCollection that allows us to configure a ContainerBuilder instance for Autofac. Awesome!

Except this doesn't work. At all. And if you read the details, here's what it says:

ONLY FOR PRE-ASP.NET 3.0 HOSTING. THIS WON'T WORK FOR ASP.NET CORE 3.0+ OR GENERIC HOSTING.

Autofac Peeps

As I mentioned, apparently I am very bad at reading. I continue to make this mistake. So let's check out the next section where we can see that the REAL solution to this is very similar... maybe just one extra line of code instead.


The Right Way to Set Up Autofac in ASP NET Core

This is what you're after, so I'll keep it short. You'll want to switch that AddAutofac() extension method to these two method calls instead:

builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
    containerBuilder.RegisterType<MyDependency>().SingleInstance();
});

Notice now that we're working with the Host property of the builder instead of the IServiceCollection. But these two methods used instead of the original one we looked at will allow you to configure your Autofac ContainerBuilder instance properly. You can also do it directly inline on the first call:

builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory(cb =>
{
    cb.RegisterType<MyDependency>().SingleInstance();
}));

From here, you can register dependencies individually, scan assemblies, load up modules -- whatever you'd like! The dependencies registered onto this container will be available to the classes that are registered on the ContainerBuilder itself AND available to the classes you have as part of the IServiceCollection. Yes, that means your minimal APIs can get all the juicy goodness now from Autofac.


Wrapping Up Autofac in ASP NET Core

As we got to see, getting Autofac in ASP NET Core is very straightforward -- IF you use the right method. After creating a video on it and writing an article, I'm hoping I never have to search for this answer again. But if I do, I know that I got myself covered! Hopefully this helped you get things configured so you can use Autofac for dependency injection in your ASP NET Core apps!

If you found this useful and you're looking for more learning opportunities, consider subscribing to my free weekly software engineering newsletter and check out my free videos on YouTube! Head over to my Discord community for hands-on help and discussions with other like-minded software engineers!