I am trying to add Autofac to a .NET 6.0 web API and read Autofac components configuration from a JSON file. I'm using the latest ASP.NET Core Web API template that generates a single start-up Program.cs file.
Installed Autofac versions:
Autofac.Configuration (6.0.0)
Autofac.Extensions.DependancyInjection (8.0.0)
Installed .NET 6.0 versions:
Microsoft.AspNetCore.App 6.0.20
Microsoft.NETCore.App 6.0.20
Just in case of doubt, this is the entire content of the Program.cs file (yes, no namespaces or class definition. Only a Program.cs file and no StartUp class or Startup.cs file)
var configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddJsonFile("autofac.json");
var autoFacConfigurationModule = new ConfigurationModule(configurationBuilder.Build());
var temp = new IpTablesDotNetSystem();
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory((containerBuilder) =>
{
containerBuilder.RegisterModule(autoFacConfigurationModule);
//containerBuilder.RegisterType<IpTablesDotNetSystem>().As<IIpTablesSystem>().SingleInstance();
}
));
// 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.UseAuthorization();
app.MapControllers();
app.Run();
But I got exception like below:
System.InvalidOperationException: Unable to resolve service for type 'BSN.IpTables.Domain.IIpTablesSystem' while attempting to activate 'BSN.IpTables.Api.Controllers.HomeController'.
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
at lambda_method364(Closure , IServiceProvider , Object[] )
at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.<>c__DisplayClass7_0.<CreateActivator>b__0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass6_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
As you can see in the above code, if I uncomment
containerBuilder.RegisterType<IpTablesDotNetSystem>().As<IIpTablesSystem>().SingleInstance();
instead of RegisterModule
all of project is correct working. but I need read configuration from files, and does not know how to do it?
I've tried looking through the latest Autofac documentation, but I did not find anything to fit with .NET 6.0 code. I can't figure out how to use the Autofac configuration.
Code snippet from the Autofac website:
// Add the configuration to the ConfigurationBuilder.
var config = new ConfigurationBuilder();
// config.AddJsonFile comes from Microsoft.Extensions.Configuration.Json
// config.AddXmlFile comes from Microsoft.Extensions.Configuration.Xml
config.AddJsonFile("autofac.json");
// Register the ConfigurationModule with Autofac.
var module = new ConfigurationModule(config.Build());
var builder = new ContainerBuilder();
builder.RegisterModule(module);
Autofac documentation:
https://autofac.readthedocs.io/en/latest/configuration/xml.html#quick-start
My complete project:
https://github.com/BSVN/IpTables.Api/pull/9
Update
My latest autofac.json file is like below:
{
"components": [
{
"type": "BSN.IpTables.Data.IpTablesDotNetSystem, BSN.IpTables.Data",
"services": [
{
"type": "BSN.IpTables.Domain.IIpTablesSystem, BSN.IpTables.Domain"
}
],
"instanceScope": "single-instance"
}
]
}