Following the AutoFac documentation, I was able to use AutoFac in ASP.NET Core 3.0 Preview 3. ASP.NET Core 3.0 Preview 4 and ASP.NET Core 3.0 Preview 5 introduced breaking changes and AutoFac no longer works. My controller methods return runtime errors.
The differences between ASP.NET Core 3.0 Preview 3 and ASP.NET Core 3.0 Preview 5 in my code is as follows:
IWebHostBuilder -> IHostBuilder
CreateWebHostBuilder -> CreateHostBuilder
WebHost.CreateDefaultBuilder(args) -> Host.CreateDefaultBuilder(args)
public IServiceProvider ConfigureServices(IServiceCollection services)
to
public void ConfigureServices(IServiceCollection services)
System.AggregateException
HResult=0x80131500
Message=Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: API.Controllers.CityController Lifetime: Transient ImplementationType: CityController': Unable to resolve service for type 'IUnitOfWork' while attempting to activate 'CityController'.) (Error while validating the service descriptor 'ServiceType: LocationController Lifetime: Transient ImplementationType: LocationController': Unable to resolve service for type 'IUnitOfWork' while attempting to activate 'LocationController'.) (Error while validating the service descriptor 'ServiceType: PersonController Lifetime: Transient ImplementationType: PersonController': Unable to resolve service for type 'IUnitOfWork' while attempting to activate 'PersonController'.) (Error while validating the service descriptor 'ServiceType: SchoolController Lifetime: Transient ImplementationType: SchoolController': Unable to resolve service for type 'IUnitOfWork' while attempting to activate 'SchoolController'.) (Error while validating the service descriptor 'ServiceType: TestParentController Lifetime: Transient ImplementationType: TestParentController': Unable to resolve service for type 'IUnitOfWork' while attempting to activate 'TestParentController'.) (Error while validating the service descriptor 'ServiceType: TypeController Lifetime: Transient ImplementationType: TypeController': Unable to resolve service for type 'IUnitOfWork' while attempting to activate 'TypeController'.)
Source=Microsoft.Extensions.DependencyInjection
StackTrace:
at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable`1 serviceDescriptors, ServiceProviderOptions options)
at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options)
at Microsoft.Extensions.DependencyInjection.DefaultServiceProviderFactory.CreateServiceProvider(IServiceCollection containerBuilder)
at Microsoft.Extensions.Hosting.Internal.ServiceFactoryAdapter`1.CreateServiceProvider(Object containerBuilder)
at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
at Microsoft.Extensions.Hosting.HostBuilder.Build()
at API.Program.Main(String[] args) in C:\Projects\FirstResponse\API\Program.cs:line 13
Inner Exception 1:
InvalidOperationException: Error while validating the service descriptor 'ServiceType: CityController Lifetime: Transient ImplementationType: CityController': Unable to resolve service for type 'IUnitOfWork' while attempting to activate 'CityController'.
Inner Exception 2:
InvalidOperationException: Unable to resolve service for type 'IUnitOfWork' while attempting to activate 'CityController'.
Program.cs
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder
.UseStartup<Startup>()
.ConfigureLogging((hostingContext, builder) =>
{
builder.ClearProviders();
builder.SetMinimumLevel(LogLevel.Trace);
builder.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
builder.AddConsole();
builder.AddDebug();
})
.UseNLog();
});
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services
.AddCustomOptions(Configuration)
.AddCors()
.AddJwtAuthentication()
.AddHttpClients()
.AddCustomMVC()
.AddIIS()
.AddCaching()
.AddCustomDbContext(Configuration, Environment)
.AddSwagger()
.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies())
.AddHealthChecksUI();
var serviceProvider = services.BuildServiceProvider();
_appSettings = serviceProvider.GetService<IOptionsSnapshot<AppSettings>>().Value;
var connectionString = Configuration.GetConnectionString(nameof(FirstResponseContext));
// Create a Autofac container builder
var builder = new ContainerBuilder();
// Read service collection to Autofac
builder.Populate(services);
// Use and configure Autofac
builder.RegisterModule(new MediatorModule());
builder.RegisterModule(new ApplicationModule(connectionString));
// build the Autofac container
ApplicationContainer = builder.Build();
// creating the IServiceProvider out of the Autofac container
//return new AutofacServiceProvider(ApplicationContainer);
}
ApplicationModule.cs
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>().SingleInstance();
builder.RegisterType<ModelValidationAttribute>().InstancePerLifetimeScope();
builder.RegisterType<ETagCache>().InstancePerLifetimeScope();
builder.RegisterType<FirstResponseContext>().As<DbContext>().As<IUnitOfWork>().InstancePerLifetimeScope();
}
Autofac is a . Net-based IoC container. When classes interact with one another, it manages the dependencies between them that allow applications to remain flexible as they grow in size and complexity. Autofac is the most widely used DI/IoC container for ASP.NET, and it is fully compatible with.NET Core as well.
Autofac is an IoC container for Microsoft . NET. It manages the dependencies between classes so that applications stay easy to change as they grow in size and complexity.
AutoFac is an Inversion of Control container that resolves dependencies of an application. This means that it also is a dependency injection framework.
A few changes would need to be done to conform to the new syntax
You need to plug in the service provider factory for AutoFac
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory()) //<--NOTE THIS
.ConfigureWebHostDefaults(webBuilder => {
webBuilder
.UseStartup<Startup>()
.ConfigureLogging((hostingContext, builder) => {
builder.ClearProviders();
builder.SetMinimumLevel(LogLevel.Trace);
builder.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
builder.AddConsole();
builder.AddDebug();
})
.UseNLog();
});
Then in the ConfigureContainer
method of your Startup
class, register things directly into an Autofac ContainerBuilder
.
public IConfigurationRoot Configuration { get; private set; }
public void ConfigureServices(IServiceCollection services) {
services
.AddCustomOptions(Configuration)
.AddCors()
.AddJwtAuthentication()
.AddHttpClients()
.AddCustomMVC()
.AddIIS()
.AddCaching()
.AddCustomDbContext(Configuration, Environment)
.AddSwagger()
.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies())
.AddHealthChecksUI();
}
public void ConfigureContainer(ContainerBuilder builder) {
var connectionString = Configuration.GetConnectionString(nameof(FirstResponseContext));
// Use and configure Autofac
builder.RegisterModule(new MediatorModule());
builder.RegisterModule(new ApplicationModule(connectionString));
}
The IServiceProvider
will automatically be created for you, so there’s nothing you have to do but register things.
Some of this was taken directly from Autofac documentation for Asp.Net Core
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With