-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Never call BuildServiceProvider #465
Comments
Ugh, yes. Just create an IStartupFilter and run the initialization code when it's called, you can inject dependencies to it and it only runs once when the host is being built. You can just leave the pipeline alone at that point. |
We should make a note to update the docs, then: |
Does it help to point out that the serviceProvider in question is only used to seed the database before tests are run, and isn't part of the actual application or the app's service provider? It's literally only needed because EF needs a scope. |
It doesn't hurt, but modifying updating the sp and the pipeline is fair game |
I don't follow. The linked doc also resolves services like an ILogger, creating duplicate singleton logging services in an app which has caused issues in the past. In the average test app this might be harmless, but it's not a pattern we should ever recommend. |
Fair enough and good point. We should update it there and here, then. |
If this were a normal app, not a test fixture, the guidance would be to move that code into Program.Main between Build and Start/Run. That way the service collection has already been built by the host, but the app hasn't fully started yet. For a WebApplicationFactory test fixture, it looks like you need to override |
@Tratcher overriding
If this method exists, then Once this is added the problem is I get a totally different issue, instead of resolving the in memory dbcontext, I get my tests running against the database! |
Following the suggestion of overriding the CreateHost to resolve any needed services, I got first into an issue of not actually having called the CreateHost I've overridden. This seems is called only once the IWebHostBuilder is changed with IHostBuilder in Program.cs (dotnet-architecture/eShopOnWeb#465) After this change, the tests aren't using the InMemory database anymore, but they actually run against the SqlServer, thus ConfigureServices or ConfigureTestServices is not used as expected.
With .Net 6.0 you can now no longer count on ConfigureWebHost being called at all if you're using top level statements in your main server code. This is because you are now creating a DeferredHostBuilder. This one will still get passed to CreateHost however. You can then configure it as an IWebHostBuilder by manually calling ConfigureWebHost on it. |
@Tratcher Do you have any updated guidance on this? I would like to have this repo reflect the latest guidance for .NET 6 but the docs for integration tests still show the pattern used in this repo for configuring and seeding data before tests. If/when the docs are updated or specific changes are suggested here I'll be happy to update this but for now I'm going to close this issue since I don't see any immediate resolution forthcoming. Thanks! |
@ardalis I've filed dotnet/AspNetCore.Docs#24204 to address this in the docs. |
Thanks, I'm watching it. Once we have concrete guidance on how to perform data seeding without using BuildServiceProvider I'll update these samples accordingly. |
eShopOnWeb/tests/FunctionalTests/Web/WebTestFixture.cs
Line 44 in fa8839e
This is an anti-pattern that causes issues with the service lifetimes (e.g. it can create multiple instances of singletons).
@javiercn can you suggest a better pattern for consuming services in a WebApplicationFactory fixture?
The text was updated successfully, but these errors were encountered: