simpleinjector / SimpleInjector.Integration.AspNetCore

MIT License
2 stars 3 forks source link

Add AddAspNetCore overload that allows overriding the IServiceScope reuse behavior #3

Closed dotnetjunkie closed 4 years ago

dotnetjunkie commented 4 years ago

When calling services.AddSimpleInjector(), Simple Injector allows pulling dependencies from the built-in .NET Core configuration system (through a mechanism called "cross wiring"). When a Simple Injector-composed component depends on a service that is registered in the built-in configuration system, it will request that service from there.

In case such dependency is scoped, however, the .AddSimpleInjector() integration ensures that such service is resolved from .NET Core's IServiceScope. It does so by resolving the IServiceScope from a Simple Injector Scope. In other words, IServiceScope itself becomes a Scoped dependency in Simple Injector.

Within the context of ASP.NET Core, however, this behavior of having one IServiceScope per Simple Injector Scope, has some downsides. ASP.NET Core allows request-specific data to be retrieved using services that are stored in a IServiceScope. This would mean that, in case you start a new Simple Injector Scope, you lose the ability to get this information from core services.

This is why the ASP.NET Core integration for Simple Injector changes this scoping behavior and ensures that within a single web request, Simple Injector always uses the same (by ASP.NET Core created) IServiceScope instance, independently of how many (nested) Scope instances are created.

An unfortunate consequence of this, however, is that a cross-wired DbContext will be reused for the duration of a web request, even if nested scopes are created. This is -especially- problematic when using Blazor Service, because Blazor will let a IServiceScope live "for as long as the user is on the page with the Blazor Component (i.e., as long as the SignalR connection is open)." (as described here) This, again, is problematic, because this could lead to concurrency issues, because the user is able to run requests in parallel.

To accommodate this, the Simple Injector user should be able to change how IServiceScope instances are reused. I see three options:

Related to: