ServiceProviderCache adds more and more IServiceProviders when running integration tests
See original GitHub issueWhen running .NET Core integration tests using WebApplicationFactory the ServiceProviderCache seems to add more and more IServiceProviders for each test until the limit of twenty is reached. By then a warning is logged or an error is thrown depending on how it’s configured.
If the DbContext is configured to throw an error, this is the exception thrown:
Exception message:
System.InvalidOperationException: Error generated for warning 'Microsoft.EntityFrameworkCore.Infrastructure.ManyServiceProvidersCreatedWarning: More than twenty 'IServiceProvider' instances have been created for internal use by Entity Framework. This is commonly caused by injection of a new singleton service instance into every DbContext instance. For example, calling UseLoggerFactory passing in a new instance each time--see https://go.microsoft.com/fwlink/?linkid=869049 for more details. Consider reviewing calls on 'DbContextOptionsBuilder' that may require new service providers to be built.'. This exception can be suppressed or logged by passing event ID 'CoreEventId.ManyServiceProvidersCreatedWarning' to the 'ConfigureWarnings' method in 'DbContext.OnConfiguring' or 'AddDbContext'.
Stack trace:
at Microsoft.EntityFrameworkCore.Diagnostics.EventDefinition.Log[TLoggerCategory](IDiagnosticsLogger`1 logger, WarningBehavior warningBehavior, Exception exception)
at Microsoft.EntityFrameworkCore.Internal.CoreLoggerExtensions.ManyServiceProvidersCreatedWarning(IDiagnosticsLogger`1 diagnostics, ICollection`1 serviceProviders)
at Microsoft.EntityFrameworkCore.Internal.ServiceProviderCache.<>c__DisplayClass4_0.<GetOrAdd>b__2(Int64 k)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Microsoft.EntityFrameworkCore.Internal.ServiceProviderCache.GetOrAdd(IDbContextOptions options, Boolean providerRequired)
at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
at Microsoft.EntityFrameworkCore.DbContext.Microsoft.EntityFrameworkCore.Internal.IDbContextDependencies.get_EntityFinderFactory()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_Finder()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.FindAsync(Object[] keyValues)
Steps to reproduce
https://github.com/mlassbo/ServiceProviderCacheProblem
Further technical details
EF Core version: 2.2.4 Database Provider: Microsoft.EntityFrameworkCore.InMemory Operating system: Windows 10 IDE: Visual Studio 2019 16.1.3
Issue Analytics
- State:
- Created 4 years ago
- Reactions:1
- Comments:16 (9 by maintainers)
Top Results From Across the Web
Integration tests in ASP.NET Core
Integration tests confirm that two or more app components work together to produce an expected result, possibly including every component ...
Read more >c# - Integration test with WebApplicationFactory fails ...
When I run the test, I get the following exception thrown. System.ObjectDisposedException : Cannot access a disposed object.
Read more >A Better Story for Asp.Net Core Integration Testing | nance.io
The test runs inside a transaction that gets rolled back when the test completes. This allows other tests to assume the database is...
Read more >Integration Testing with ASP.NET Core 3.1 - Adam Storr
Investigating how to write integration tests while swapping out dependencies with mocked instances using Moq. Published on 23 December 2019.
Read more >ASP.NET Core Dependency Injection - Steve Gordon
In this post, I explain what an IServiceProvider is and how it can be created and later used to resolve dependencies in ASP.NET...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
I have run into this issue as well when running integration tests with the InMemory database provider. I tried to use
EnableServiceProviderCaching(false)but found that my tests took over 4 min to run (compared to 40 seconds in EF Core 2.2). I was able to just follow the info in the error to disable to ignore the warning/error and all my tests still work and they run in around 45 seconds like they did in v2.2.The issue here is that each test is effectively spinning up a completely new web app. This means that services we get from ASP.NET are different every test, which in turn means a new internal service provider for every test.
@mlassbo The current workarounds is to manage the internal service provider manually using
DbContextOptionsBuilder.UseInternalServiceProvider. However, it’s also worth mentioning that building and throwing away so much for each test could end up being very slow. This is both because setting everything up is a lot of work, and also because the caching that is set up is usually very important for good perf.Notes for triage:
Things should be better in 3.0, since we don’t need to build a new service provider for a new
ILoggerFactory, and we don’t depend onIMemoryCacheanymore. It would be useful to know if there are other services that can cause this–possiblyIConfigurationfor example.The workaround for 3.0 is also easier, since we added
options.EnableServiceProviderCaching(false).