Reputation: 1632
In ASP.NET Core 3.x, the usage of IoC containers like Autofac changed. Instead of returning some adapter instance in ConfigureServices
, we have to use the new ConfigureContainer
method.
My question is: how can I access the Autofac IContainer instance in the Configure
method? I tried to call containerBuilder.Build
within ConfigureContainer
, to get a reference to the container instance, but then I get an exception that the container can only built once.
I am well aware that in normal use cases, there should be no need to pass around the container (Service Locator anti pattern etc.....). However, in this special case, we are using a middleware that resolves Command and Event handler types and it is based on Autofac. It needs the container instance.
Any chance to reference the IContainer
instance once it has been built by the framework?
Upvotes: 2
Views: 1277
Reputation: 8740
In order to get a hold of an IContainer
instance you can follow the solution from the autofac documentation (link):
// Configure is where you add middleware. This is called after // ConfigureContainer. You can use IApplicationBuilder.ApplicationServices // here if you need to resolve things from the container. public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) { // If, for some reason, you need a reference to the built container, you // can use the convenience extension method GetAutofacRoot. this.AutofacContainer = app.ApplicationServices.GetAutofacRoot(); loggerFactory.AddConsole(this.Configuration.GetSection("Logging")); loggerFactory.AddDebug(); app.UseMvc(); }
The GetAutofacRoot();
in an extension method in Autofac.Extensions.DependencyInjection
.
So in order to hold a reference on a casted IContainer
you can write:
IContainer container = (IContainer)app.ApplicationServices.GetAutofacRoot();
This cast is valid because IContainer : ILifetimeScope
Upvotes: 2
Reputation: 16192
If you really need to have dependency on the container you should add a dependency on ILifetimeScope
and then resolve from this scope.
public class FooMiddleware
{
public FooMiddleware(RequestDelegate next)
{
this._next = next;
}
private readonly RequestDelegate _next;
public async Task InvokeAsync(HttpContext context, ILifetimeScope scope)
{
scope.Resolve<Foo>();
await this._next(context);
}
}
Upvotes: 0