autofac / Autofac.Extensions.DependencyInjection

Autofac implementation of the interfaces in Microsoft.Extensions.DependencyInjection.Abstractions, the .NET Core dependency injection abstraction.
MIT License
196 stars 47 forks source link

Using Autofac in .Net 6.0 #97

Closed Github-User-202 closed 2 years ago

Github-User-202 commented 2 years ago

Problem Statement

I am trying to add Autofac to a .Net 6.0 web API (with the RC assemblies). I'm using the latest ASP.NET Core Web API template that generates a single start-up Program.cs file with a new pipeline. My question was when would Autofac be able to integrate with this new pipeline?

This is the new Program.cs file, no Startup class anymore


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()
tillig commented 2 years ago

Autofac.WebApi is for classic ASP.NET Web API 5.2, not ASP.NET Core / .NET 6. You're using the Autofac.Extensions.DependencyInection package to integrate with .NET 6.

I'm going to transfer the issue there before answering.

tillig commented 2 years ago

Autofac uses the standard .NET integration provided by ASP.NET Core. The integration isn't Autofac-specific, it's just an implementation of the hooks provided by .NET Core.

For the time being, we don't have examples of .NET 6 integration with the new "minimal API" but you should search for things that aren't Autofac-specific to be successful, like "minimal API .net 6 dependency injection" - you'll find things like you can have a Startup if you want, by doing things like:

var builder = WebApplication.CreateBuilder(args);
builder.Host.ConfigureWebHostDefaults(webBuilder =>
{
    webBuilder.UseStartup<Startup>();
});
using var app = builder.Build();
app.Run();

It might be worthwhile checking out examples like our Startup-free .NET Core 3 example to start figuring out how to integrate using the minimal API scenario.

However, there's no action here for Autofac to take, maybe beyond providing an example. How to integrate with any DI container or do, honestly, any of the stuff you used to do in the Program/Startup world, is a question for the .NET team.

And it may be that to do some of the things beyond the most basic operations you don't get to use the minimal API stuff. The .NET team has made decisions like that before - for the really simple stuff, here's an easy way to do it; for something where you're integrating custom DI / custom logging / custom something else... you have to put the boilerplate in still.

If you figure it out, we'd welcome a PR to the Examples repo or the Documentation repo to help others out.

alistairjevans commented 2 years ago

It is worth pointing that we do have a preview Nuget release for .NET 6 to support the automatic service vs route parameter detection features in .NET 6. https://github.com/autofac/Autofac.Extensions.DependencyInjection/releases/tag/v7.2.0-preview.1

alistairjevans commented 2 years ago

I do happen to have a minimal example lying around from when we did that. As @tillig said, we're not doing anything special here, just using the standard .NET6 DI stuff with an AutofacServiceProviderFactory.


using Autofac.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory(builder =>
{
    // do custom registration
}));

var app = builder.Build();

app.MapGet("/", () => "hello world");

app.Run();
Trifunovich commented 2 years ago

@alistairjevans yeah, mine is similar to yours

using Autofac.Extensions.DependencyInjection;
using DataServiceProvider.fml.DependencyInjection;
using LoggingLibrary.DiResolver;

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

builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory(containerBuilder =>
{
    //internal registries
    containerBuilder.RegisterDataServiceProviderDependencies();
    containerBuilder.AddLoggingServices(builder.Configuration);
}));

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