Search code examples
c#asp.net-coreautofac.net-6.0

Autofac with .NET 6 console app and ServiceCollection


I am trying to use ServiceCollection with Autofac populating the ServiceCollection in a Console App. I read through the documentation but there is no guide for my specific scenario.

The issue I am facing is that built ServiceCollection does not find the implementation when I ask with interface type. I think AutoFac is not populating the ServieCollection.

Program.cs

using System.Reflection;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Core.Interfaces;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;


var serviceProvider = new ServiceCollection()
    .AddLogging(cfg => cfg.AddConsole())
    .Configure<LoggerFilterOptions>(cfg => cfg.MinLevel = LogLevel.Information)
    .AddAutofac(cfg =>
    {
        cfg.RegisterAssemblyTypes(Assembly.Load("Core")).AsImplementedInterfaces();
    })
    .BuildServiceProvider();

var markDownParser = serviceProvider.GetRequiredService<IMarkDownParser>();

MarkDownParser.cs

namespace Core;

public class MarkDownParser : IMarkDownParser
{
    private readonly ILogger<MarkDownParser> _logger;

    public MarkDownParser(ILogger<MarkDownParser> logger)
    {
        _logger = logger;
    }
}

IMarkDownParser.cs

namespace Core.Interfaces;

public interface IMarkDownParser
{
    object Parse(string text);
}

Error:

Unhandled exception. System.InvalidOperationException: No service for type 'Core.Interfaces.IMarkDownParser' has been registered.
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Program.<Main>$(String[] args) in /home/amir/RiderProjects/git-blog/ConsoleApp/Program.cs:line 20

Solution

  • I think the problem is on AddAutofac extension method only supports during ASP.NET Core 1.1 - 2.2.

    This is not for ASP.NET Core 3+ or the .NET Core 3+ generic hosting support - ASP.NET Core 3 has deprecated the ability to return a service provider from ConfigureServices.

    if we want to use autofac to be the DI Container, there is an example to talk about netcore quick-start

    Once you've registered everything in the ServiceCollection and call Populate to bring those registrations into Autofac by ContainerBuilder

    Final, Creating a new AutofacServiceProvider makes the DI container and we can use that.

    var serviceCollection = new ServiceCollection()
        .AddLogging(cfg => cfg.AddConsole())
        .Configure<LoggerFilterOptions>(cfg => cfg.MinLevel = LogLevel.Information);
    
    var containerBuilder = new ContainerBuilder();
    containerBuilder.Populate(serviceCollection);
    containerBuilder.RegisterAssemblyTypes(Assembly.Load("Core")).AsImplementedInterfaces();
    var container = containerBuilder.Build();
    
    var serviceProvider = new AutofacServiceProvider(container);
    var markDownParser = serviceProvider.GetRequiredService<IMarkDownParser>();