26

I need ti use this AutoFac in ASP core 3.0

When I use this code in startu up:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    return services.BuildAutofacServiceProvider();
}

It show me this error:

'ConfigureServices returning an System.IServiceProvider isn't supported.'

And I change the program.cs by this:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
        .UseServiceProviderFactory(new AutofacServiceProviderFactory())
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

But it not solved.

This is BuildAutofacServiceProvider() Code:

public static IServiceProvider BuildAutofacServiceProvider(this IServiceCollection services)
{
    var ContainerBuilder = new ContainerBuilder();
    ContainerBuilder.Populate(services);
    ContainerBuilder.AddService();
    var container = ContainerBuilder.Build();

    return new AutofacServiceProvider(container);
}

How can I solve this problem?

Nkosi
  • 235,767
  • 35
  • 427
  • 472
mr-dortaj
  • 782
  • 4
  • 11
  • 28

4 Answers4

35

Startup syntax has changed for configuring Autofac for ASP.NET Core 3.0+

In addition to using the following on the host builder

.UseServiceProviderFactory(new AutofacServiceProviderFactory())

In Startup do the following format

public void ConfigureServices(IServiceCollection services) {
    //... normal registration here

    // Add services to the collection. Don't build or return
    // any IServiceProvider or the ConfigureContainer method
    // won't get called.

    services.AddControllers();
}

// ConfigureContainer is where you can register things directly
// with Autofac. This runs after ConfigureServices so the things
// here will override registrations made in ConfigureServices.
// Don't build the container; that gets done for you. If you
// need a reference to the container, you need to use the
// "Without ConfigureContainer" mechanism shown later.
public void ConfigureContainer(ContainerBuilder builder) {
    // Register your own things directly with Autofac
    builder.AddMyCustomService();

    //...
}

Reference Autofac documentation for ASP.NET Core 3.0+

Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • 9
    It's somewhat important to note that this isn't an Autofac-specific change. ASP.NET Core 3.0 stopped supporting returning an `IServiceProvider` when they switched to use the generic application host. Using a service provider factory is now the only way to integrate any third-party DI container. – Travis Illig Sep 27 '19 at 19:47
  • @TravisIllig Thanks for pointing this out! But I've got one question: is builder.Populate(services) still workable and needed? – Henry Roeland Dec 09 '19 at 18:26
  • 1
    No. It'd be good if you read the documentation linked in the answer here, it has a total walkthrough with examples. – Travis Illig Dec 09 '19 at 18:28
6

Instead of Host in Program.cs you can use WebHost

public class Program
{
  public static void Main(string[] args)
  {
    CreateWebHostBuilder(args).Build().Run();
  }

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

In this case following code works

public IServiceProvider ConfigureServices(IServiceCollection services)
{
  ...
  var builder = new ContainerBuilder();

  builder.Populate(services);
  var container = builder.Build();
  return new AutofacServiceProvider(container);
}
R.Titov
  • 3,115
  • 31
  • 35
0

you must change program.c

public static void Main(string[] args)
{
    CreateWebHostBuilder(args).Build().Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
   WebHost.CreateDefaultBuilder(args)
       .ConfigureLogging(options => options.ClearProviders())
       .UseStartup<Startup>();
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 05 '22 at 07:36
-1

Instead of Host use WebHost in Program.cs

It work for me ...

  • This looks more like a comment to [this answer](https://stackoverflow.com/a/63701478/2227743) rather than a new answer. – Eric Aya Feb 12 '22 at 09:58
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 12 '22 at 12:17
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/31052559) – Martinaut Feb 18 '22 at 09:08