-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Explicit test for injecting scoped IServiceProvider into scoped and transient services (#63225) #63226
Closed
lord-executor
wants to merge
1
commit into
dotnet:main
from
lord-executor:service-provider-scoped-injection-test
Closed
Explicit test for injecting scoped IServiceProvider into scoped and transient services (#63225) #63226
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is breaking the original intention of this test. See dotnet/extensions#2236 and dotnet/extensions#1301 for more information on why this test was written this way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm... I don't think so. The fact that the instances are the same is not strictly necessary for #1301. All that is really needed is that the two providers are bound to the same (root) scope which the new version is validating with
In fact, if you add the very simple test
Then that fails for Grace, LightInject, Autofac and StashBox because they do not actually ensure that the service provider is the same instance. They do however ensure that the instances are tied to the same scope which is what these changes here are testing. Ensuring reference equality of the provider instance is sufficient, but not necessary. As long as the scope is the right one, the problem in #1301 should be solved.
And I did a similar test for scopes which generates similarly entertaining failures with the same set of containers and additionally DryIoc and Lamar also fail that one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I actually enable that singleton test for Unity (where it is currently still disabled), then it does still fail that test, but in an "interesting" way:
Meaning that when it tries to resolve the fake service in the second scope, it can't find a registration for
IFakeService
. This is admittedly not what I was expecting.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to be clear. I'll of course revert the changes to this test if you prefer, but I do think that the reference equality testing on the service provider is unnecessary and misleading as demonstrated by my two simple demo tests above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is for Singleton services, and both those demo tests use Scoped services.
For Singleton services, I believe the intention is that the ServiceProvider they get is the root provider, and thus they should be the same.
@davidfowl - you originally wrote the test. Do you have any thoughts here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this test is for Singleton services. And the
ClassWithServiceProvider
is still registered as a singleton and thus should be injected with the root provider. The scopedIFakeService
is just my "canary in the coal mine" for figuring out if the singleton was actually injected with the root scope. It still tests the same scenario, just in a different way.scopedFakeServiceFromScope1
is resolved from the scope's service provider => that should be a fresh instance bound toscope1
fakeServiceFromScope1
is resolved from the service provider that was injected into the singleton which should be the root scope => that should give me a different instance toscopedFakeServiceFromScope1
scope2
and compare results based on where we expect the same or different instancesThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw. the reason for the weird failure mode of Unity in the Singleton scenario has actually already been explained by @davidfowl in #extensions/1301 I just didn't read his explanation carefully enough.
Unity fails for the same reason it failed before, because it injects the
scope1
service provider into the singleton. That scope is then disposed and in the code forscope2
it is trying to resolve a service through this already disposedscope1
service provider which fails because it can no longer find theIFakeService
registration.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me take a deeper look at this today. On second glance I can see why my test would make other containers fail. The service provider instance isn't as important as the lifetime of the objects that come out of it.