10

We're using Sitecore 8.2, habitat.

I have a service that I need to use throughout a full HTTP Request. This service should be instantiated once (we use dependancy injection) and then be available everywhere else through DI. I have added the service as AddScoped<T> and this is working correctly when I'm instantiating the service in controllers for example.

However, the business requirements have now changed, and we need this service available during all times of the execution of a httpRequest.

Normally speaking I'd just edit the global.asax file (RequestBegin and RequestEnd) to instantiate the service, but in Sitecore 8.2 this is bad-practise.

What have I tried: I've added a pipeline processor (httpRequestBegin and httpRequestEnd) with resolve=true to resolve the service from the constructor of the processor.

Result: The application is resolving the service like it should, however it doesn't follow the dependancy injection rules of AddScoped<T> because I see the service being instantiated a second time on controllers later on in the request pipeline. This means the service is instantiated twice, which is a problem for me (we need 1 service per request).

Perhaps someone can point me in the right direction - why does sitecore instantiate the service twice in this case?

Note: it instantiates it once for the processor, and then only once for the all controllers and other services / repositories being called. So it is working, but it seems there are two scopes or something.

Any tips / help in the right direction?

  • did you ever resolve this? I am seeing the same behavior and am stumped... – Jason Booth Jun 19 '18 at 20:50
  • We ran into this exact issue today on Sitecore 8.2 Update 6. Our solution was to use the Service Locator anti-pattern in the processor to get our service. This properly instantiated it once for the life of the request, across the container. Has to be a Sitecore bug... – Jason Booth Jun 19 '18 at 21:54
  • @JasonBooth we never resolved this. We are in the middle of upgrading to 9.0 so perhaps we'll see some change there. For now we worked around it by building a singleton (static) class with lazy initializers. Not the perfect solution, but it works. – Erik J. Jun 24 '18 at 18:09
2

Sitecore pipeline processors are cached after instantiation, if memory serves, so the dependencies to them are injected exactly once - thus the container is not consulted every time a pipeline is run. To create each pipeline processor for every run would be quite expensive, and some pipelines are very tight loop (i.e. renderField).

To work around this, you can inject a singleton factory dependency that you can request your request-scoped object from (i.e. _myIObjectFactory.GetCurrentObject()). The implementation of this factory could proxy to service locator, or HttpContext.Current.Items.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.