-
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
Fix validation on build #87354
Fix validation on build #87354
Conversation
Tagging subscribers to this area: @dotnet/area-extensions-dependencyinjection Issue DetailsLet's look at the following example interface IBar {}
class Bar1 : IBar {}
class Bar2 : IBar {}
services.AddScoped<IBar, Bar1>(); // Slot: 1
services.AddTransient<IBar, Bar2>(); // Slot: 0
var sp = services.BuildServiceProvider(validateScopes: true);
Debug.Assert(sp.GetService<IBar>() is Bar2) The last implementation will be resolved by convention. For more details see the
|
@@ -97,6 +98,12 @@ public void ValidateResolution(Type serviceType, IServiceScope scope, IServiceSc | |||
|
|||
protected override Type? VisitFactory(FactoryCallSite factoryCallSite, CallSiteValidatorState state) => null; | |||
|
|||
private static ServiceCacheKey GetCacheKey(ServiceCallSite callSite) | |||
{ | |||
return callSite.Cache.Key.Equals(ServiceCacheKey.Empty) |
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.
The call to callSite.Cache.Key
should only ever occur once for perf.
{ | ||
OnResolve(callSite, scope); | ||
DependencyInjectionEventSource.Log.ServiceResolved(this, serviceType); | ||
return realizedService.Invoke(scope); |
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.
.Invoke()
is unnecessary.
} | ||
|
||
[Fact] | ||
public void ScopeValidation_ShouldBeAbleToDistingushGenericCollections_WhenGetServiceIsCalledOnRoot() |
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.
It appears this passes without the changes here. Is that intentional?
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, It is intentional. It tests the GetCacheKey()
private method that replaces ResultCache.None
for services. (For instance, IEnumerable<Foo>
and IEnumerable<Bar>
have the same ResultCache
that is equal to ResultCache.None
if at least one of the Foo
and at least one of the Bar
have transient lifetime)
Please add a corresponding issue and link to it from this PR. Thanks |
Fix #87429 |
Failure on runtime known issue. |
Thanks @mapogolions |
Fixes #87429
Let's look at the following example
The last implementation will be resolved by convention. For more details see the
CallSiteFactory
class and theDefaultSlot
property. The scope validation is fine with a service lifetime (GetService for Transient service on the Root scope).But the behavior breaks when we set the
ValidateOnBuild
property to 'true'. Please see unit tests that reproduce the issue.