Creating a AsyncScopedLifestyle scope inside of a ASP.NET Core web request does not result in a new scoped service when this service is resolved via Simple Injector ASP.NET Core cross wiring. Instead, it is resolving the same instance as in the other scope.
I could only reproduce this issue in a ASP.NET Core app, I have attached a solution (Cross wiring issue.zip) that demonstrates the issue.
Below a snippet that produces the issue:
Resolve using cross wiring
The CoreScopedService is registered in the ServiceCollection and cross wired using Simple Injector.
Throws because scopedService1 and scopedService2 are the same instance.
CoreScopedService scopedService1;
CoreScopedService scopedService2;
using (var scope = AsyncScopedLifestyle.BeginScope(Startup.Container))
{
scopedService1 = scope.Container.GetInstance<CoreScopedService>();
}
using (var scope = AsyncScopedLifestyle.BeginScope(Startup.Container))
{
scopedService2 = scope.Container.GetInstance<CoreScopedService>();
}
if (object.ReferenceEquals(scopedService1, scopedService2))
{
throw new InvalidOperationException("Same scoped service instance");
}
The same scenario is working in the following cases:
Defer resolving the instances until after the web request
Does not throw, scopedService1 and scopedService 2 are separate instances.
Task.Run(() =>
{
// Sleep so resolving is done after the request has been completed.
Thread.Sleep(1000);
CoreScopedService scopedService1;
CoreScopedService scopedService2;
using (var scope = AsyncScopedLifestyle.BeginScope(Startup.Container))
{
scopedService1 = scope.Container.GetInstance<CoreScopedService>();
}
using (var scope = AsyncScopedLifestyle.BeginScope(Startup.Container))
{
scopedService2 = scope.Container.GetInstance<CoreScopedService>();
}
if (object.ReferenceEquals(scopedService1, scopedService2))
{
throw new InvalidOperationException("Same scoped service instance");
}
});
Using SimpleInjector only
Does not throw, scopedService1 and scopedService 2 are separate instances.
SimpleInjectorScopedService scopedService1;
SimpleInjectorScopedService scopedService2;
using (var scope = AsyncScopedLifestyle.BeginScope(Startup.Container))
{
scopedService1 = scope.Container.GetInstance<SimpleInjectorScopedService>();
}
using (var scope = AsyncScopedLifestyle.BeginScope(Startup.Container))
{
scopedService2 = scope.Container.GetInstance<SimpleInjectorScopedService>();
}
if (object.ReferenceEquals(scopedService1, scopedService2))
{
throw new InvalidOperationException("Same scoped service instance");
}
Using only ASP.NET Core DI
Does not throw, scopedService1 and scopedService 2 are separate instances.
CoreScopedService scopedService1;
CoreScopedService scopedService2;
using (var scope = _serviceScopeFactory.CreateScope())
{
scopedService1 = scope.ServiceProvider.GetRequiredService<CoreScopedService>();
}
using (var scope = _serviceScopeFactory.CreateScope())
{
scopedService2 = scope.ServiceProvider.GetRequiredService<CoreScopedService>();
}
if (object.ReferenceEquals(scopedService1, scopedService2))
{
throw new InvalidOperationException("Same scoped service instance");
}
Creating a
AsyncScopedLifestylescope inside of a ASP.NET Core web request does not result in a new scoped service when this service is resolved via Simple Injector ASP.NET Core cross wiring. Instead, it is resolving the same instance as in the other scope.I could only reproduce this issue in a ASP.NET Core app, I have attached a solution (Cross wiring issue.zip) that demonstrates the issue.
Below a snippet that produces the issue:
Resolve using cross wiring
The
CoreScopedServiceis registered in the ServiceCollection and cross wired using Simple Injector.Throws because scopedService1 and scopedService2 are the same instance.
The same scenario is working in the following cases:
Defer resolving the instances until after the web request
Does not throw, scopedService1 and scopedService 2 are separate instances.
Using SimpleInjector only
Does not throw, scopedService1 and scopedService 2 are separate instances.
Using only ASP.NET Core DI
Does not throw, scopedService1 and scopedService 2 are separate instances.