The InvalidOperationException Cannot consume scoped service from singleton is a well-known scenario described very well here
I am investigating a way to reproduce this exception (assuming it comes from the Dependency Injection framework) but I am not succeeding.
I've created a repo with a commit to illustrate it but basically I have the following test:
public class Given_Scoped_Repository_And_Singleton_Service_That_Uses_The_Repository_When_Getting_Service_From_Different_Scope_After_Disposing_First_Scope
: Given_When_Then_Test
{
private IServiceScope _scopeOne;
private IServiceScope _scopeTwo;
private ServiceSample _serviceSampleOne;
private ServiceSample _serviceSampleTwo;
protected override void Given()
{
var serviceCollection =
new ServiceCollection()
.AddScoped<RepositorySample>()
.AddSingleton<ServiceSample>()
.BuildServiceProvider();
_scopeOne = serviceCollection.CreateScope();
_scopeTwo = serviceCollection.CreateScope();
_serviceSampleOne = _scopeOne.ServiceProvider.GetService<ServiceSample>();
_scopeOne.Dispose();
}
protected override void When()
{
_serviceSampleTwo = _scopeTwo.ServiceProvider.GetService<ServiceSample>();
}
[Fact]
public void Then_It_Should_Get_The_Same_Service_Instance()
{
_serviceSampleOne.Should().Be(_serviceSampleTwo);
}
[Fact]
public void Then_It_Should_Have_The_Same_Repository_Instance()
{
_serviceSampleOne.RepositorySample.Should().Be(_serviceSampleTwo.RepositorySample);
}
}
and
class RepositorySample { }
class ServiceSample
{
public RepositorySample RepositorySample { get; }
public ServiceSample(RepositorySample repositorySample)
{
RepositorySample = repositorySample;
}
}
I would expect to see that InvalidOperationException thrown because I am getting a singleton service from a different scope expecting the repository to be different (since it's scoped). These tests are not failing even if I explicitly dispose the first context that instantiated the scoped RepositorySample and I am a bit confused here.
- Why the dependency injection framework
Microsoft.Extensions.DependencyInjection 3.1.3doesn't throw the exception alerting me of the singleton-scope trap? - If I dispose the first scope (as if it was a scoped DbContext in an Mvc scenario that should die when a response is issued), shouldn't this cause the
RepositorySampleinstance to be disposed? It isn't, even when I haveRepositorySampleimplementIDisposableI can see the scoped instance is never disposed (the Dispose method is not executed) - How could I design my test to see the exception as if it was happening with a scoped DbContext that is instantiated in a singleton service?