【问题标题】:Adding Autofac to .NET core 6.0 using the new single file template使用新的单文件模板将 Autofac 添加到 .NET core 6.0
【发布时间】:2021-10-28 13:27:47
【问题描述】:

我正在尝试将 Autofac 添加到 .Net 6.0 Web API。 我正在使用最新的 ASP.NET Core Web API 模板,该模板生成单个启动 Program.cs 文件。

已安装的 Autofac 版本:

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

已安装 .Net 6.0 版本:

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

以防万一,这是 Program.cs 文件的全部内容(是的,没有命名空间或类定义。​​只有 Program.cs 文件,没有 StartUp 类或 Startup.cs 文件)

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

我已尝试查看最新的 Autofac 文档,但其中的示例虽然说 .Net Core 3.x 及更高版本似乎不适合 .Net 6.0 代码。我不知道如何将 Autofac 添加到中间件管道中。

非常感谢任何帮助。

来自 Autofac 网站的代码 sn-p

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 文档:

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

【问题讨论】:

  • Please don't double post - Autofac 的人也监控 StackOverflow。以后,只要在这里发布问题,如果我们能回答,我们就会回答。

标签: autofac asp.net-core-6.0


【解决方案1】:

我找到了这个。 https://docs.microsoft.com/en-us/aspnet/core/migration/50-to-60-samples?view=aspnetcore-5.0


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


【讨论】:

  • ConfigureContainer 是通用的,应该引用 AutoFac ContainerBuilder 类型,如下所示:builder.Host.ConfigureContainer(containerBuilder => { containerBuilder.RegisterModule(new EmptyModule()); });
  • 对于像我这样的复制粘贴者:您还需要添加 Autofac.Extensions.DependencyInjection 包,而不仅仅是 Autofac。
  • 我不知道你们是否有同样的问题,在 ConfigureContainer 中,Visual Studio 告诉我它包含配置属性但是当我想使用它时,它给我一个错误说我无法访问它..还有其他人有这个问题吗?此外,如果我想从 appsettings.json 文件中读取然后定义我想注册为 IOption 的设置,我似乎无法通过任何方式传递 IConfiguration。
【解决方案2】:

我附上了如何将Autofac 添加到.NET Core 6.0 的手动声明和反射API 的示例

  1. 在 Host 子属性上调用 UseServiceProviderFactory
  2. 在 Host 子属性上调用 ConfigureContainer
  3. 声明您的服务及其生命周期

手动服务声明示例

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

});

Assembly 扫描“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));

});

【讨论】:

    【解决方案3】:

    在“Program.cs”

    你会发现

    var builder = WebApplication.CreateBuilder(args);
    

    在下面添加

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

    上面的答案,我假设您已经设置了所有其他内容。 我正在使用 Autofac 和 Autofact.Extras.DynamicProxy

    在我的 AutofacBusinessModule 下方分享只是为了澄清。

    public class AutofacBusinessModule : Module
        {
            protected override void Load(ContainerBuilder builder)
            {
                builder.RegisterType<ProductManager>().As<IProductService>().SingleInstance();
                builder.RegisterType<EfProductDal>().As<IProductDal>().SingleInstance();
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2018-08-05
      • 2017-03-20
      • 1970-01-01
      • 2015-07-12
      • 1970-01-01
      • 1970-01-01
      • 2022-09-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多