Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No way to get scope for current http request (Autofac 4)?

How can we get ILifetimeScope for current http request when HttpContext exists? E.g. I want to resolve service from static extension method. I don't want to create new instance of scope by BeginLifetimeScope() method.

I spend few hours and didn't found solution..

like image 477
Yury Scherbakov Avatar asked Jun 17 '16 23:06

Yury Scherbakov


People also ask

How do I get Autofac containers?

From Visual Studio, you can get it via NuGet. The package name is Autofac. Alternatively, the NuGet package can be downloaded from the GitHub repository (https://github.com/autofac/Autofac/releases).

Why use Autofac?

AutoFac provides better integration for the ASP.NET MVC framework and is developed using Google code. AutoFac manages the dependencies of classes so that the application may be easy to change when it is scaled up in size and complexity.

What is InstancePerLifetimeScope?

InstancePerLifetimeScope means a new instance of the service will be created for every lifetime scope which asks for your service. Each web request gets its own fresh lifetime scope, so in practice, more often than not, these two will do the exact same thing.

What is IHttpContextAccessor?

It stores the request and response information, such as the properties of request, request-related services, and any data to/from the request or errors, if there are any. ASP.NET Core applications access the HTTPContext through the IHttpContextAccessor interface.


1 Answers

Note: this was originally cross-posted as an issue/question on Autofac where there is more context.

Based on the code posted in the Autofac issue, you basically have a reference to the application container, you can resolve an IHttpContextAccessor, and from there you can get the current HttpContext. From there you want to resolve request-level services and are stuck.

First, it's important to note that a key difference in ASP.NET Core is that it handles the request scope creation, not Autofac. In fact, ASP.NET Core handles pretty much everything as far as initiating resolution of services and so forth. Autofac backs the DI container interfaces, but the engine driving the calls to Autofac - including the creation and storage of the request scope - is all ASP.NET Core. (You can see in the ASP.NET "Hosting" repo where this happens.).

Knowing that, it can help troubleshoot issues like this - you'll know not to look in Autofac code and instead chase down things in ASP.NET Core.

What you'll notice is that on the ASP.NET Core HttpContext there is a property RequestServices. That property is the request lifetime scope for ASP.NET Core. So if you need to do a simple resolve of a service from an HttpContext, you can use that:

var accessor = _container.Resolve<IHttpContextAccessor>();
var context = accessor.HttpContext;
var resolved = context.RequestServices.GetService<MyService>();

If you absolutely must have an Autofac-specific request lifetime scope, you can resolve an ILifetimeScope from the request services. You can always resolve the current lifetime scope from a scope/container, so the scope you get will be the request scope.

var accessor = _container.Resolve<IHttpContextAccessor>();
var context = accessor.HttpContext;
var scope = context.RequestServices.GetService<ILifetimeScope>();
var resolved = scope.Resolve<MyService>();
like image 179
Travis Illig Avatar answered Nov 11 '22 04:11

Travis Illig