DI Lifetime.Request works per thread.
See original GitHub issueBrief explanation of issue on forum: https://our.umbraco.com/forum/umbraco-8//98389-iusercomposer-with-lifetimerequest-works-as-lifetimetransient
In general: All would have been ok with DI, if i didnt need custom EF db context, not related to umbraco content - my own db for a lot of businesslogic data structure, for webapi and custom mvc.
So issue in general: EntityContext.Instance() gets fired 35 times during request. I did static counter, and it is seen that it was created 35 times during request. Why Lifetime.Request doesnt create 1 instance per request? (all server side use async awaited Tasks)
Apart from that Lifetime.Request dependencies gets disposed at the end of first thread, so in controller constructor i have ok context, but in controller method it is already disposed. Also every single dependency on EntityContext has its own instance, instead 1 instance per request. So my db context and transactions are disposed before being injected. And all dependencies have different db contexts - checked by static counter with instance saved value.
Entire concept of UnitOfWork with services breaks, as i cant handle all db updates at once which is important for business logic.
I tried to create own Container and resolve DI with DependencyResolver, but entire backoffice stop to work - i can’t even login (so umbraco uses DependencyResolver), also umbraco dependent instances wasnt loaded.
Is it a known issue? i had 8.0.2 version, and then updated to 8.1 - issue still exist. The only specific thing is that i extended UmbracoDefaultOwinStartup, as it was needed for webapi. rest shouldn’t do anything to default installation.
public partial class Startup : UmbracoDefaultOwinStartup
{
public override void Configuration(IAppBuilder app)
{
base.Configuration(app);
ServicesConfig.RegisterServices(app);
FluentValidationModelValidatorProvider.Configure(x => x.AddImplicitRequiredValidator = true);
AuthConfiguration.ConfigureAuth(app);
}
protected override void ConfigureServices(IAppBuilder app, ServiceContext services)
{
base.ConfigureServices(app, services);
ServicesConfig.RegisterServices(app, services);
}
protected override void ConfigureMiddleware(IAppBuilder app)
{
base.ConfigureMiddleware(app);
}
}
Would be cool to get some answer or suggestions on forum 😃
P.S. 1 little update - just have tried after post. changed back owin startup to UmbracoDefaultOwinStartup. And now all instances being disposed after controllers method execution. Tada! (so extending UmbracoDefaultOwinStartup causes DI issues?) but still instead of 1 instance per request - many instances.
Issue Analytics
- State:
- Created 4 years ago
- Comments:22 (15 by maintainers)
@kjac Yep I agree. What we can do is obsolete and hide
Lifetime.Scope
since internally we don’t use it (well we actually do, but that’s because we actually wanted ‘one per request’ in some cases). In some cases people would want to use the container’s own Scope based lifetime but in those cases, developers can do this directly using the container by accessing theIRegister.Concrete
property to return the concrete underlying container. I can submit a PR shortly for 8.2.In the meantime, anyone wanting to have a lifetime of “one per request” must use
Lifetime.Scope
Have created a PR here https://github.com/umbraco/Umbraco-CMS/pull/6069
Have decided to not obsolete Lifetime.Scope since there will be use cases for this for some people and since this is a native feature for every container.