带有 .NET 6 控制台应用程序和 ServiceCollection 的 Autofac

Autofac with .NET 6 console app and ServiceCollection

我正在尝试使用 ServiceCollection 和 Autofac 在控制台应用程序中填充 ServiceCollection。我通读了 the documentation,但没有针对我的具体情况的指南。

我面临的问题是,当我询问接口类型时,构建的 ServiceCollection 找不到实现。我认为 AutoFac 没有填充 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);
}

错误:

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

文档说只能使用 AddAutofac
ONLY FOR PRE-ASP.NET 3.0 HOSTING. THIS WON'T WORK FOR ASP.NET CORE 3.0+ OR GENERIC HOSTING.

因为 .net 6 已被标记。我认为框架是问题的一部分。

这是我的实现以及一些帮助文档。
https://autofac.readthedocs.io/en/latest/integration/aspnetcore.html

// 主要

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

using IHost host = Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(builder =>
{
    builder.RegisterAssemblyTypes(Assembly.Load("Core")).AsImplementedInterfaces();
})
.Build();

var markDownParser = host.Services.GetRequiredService<IMarkDownParser>();
Console.WriteLine(markDownParser);

//核心组件

using Microsoft.Extensions.Logging;

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

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

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

        public object Parse(string text)
        {
           throw new NotImplementedException();
        }
    }
}

我认为问题出在 AddAutofac 扩展方法仅支持 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.

如果要用autofac做DI Container,有例子可以讲netcore quick-start

在 ServiceCollection 中注册所有内容后,调用 Populate 通过 ContainerBuilder

将这些注册导入 Autofac

最后,创建一个新的 AutofacServiceProvider 生成 DI 容器,我们可以使用它。

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>();