Description
DependsOnResolutionFunc<TTarget> and KeyedDependsOnResolutionFunc<TTarget> in ServiceCollectionExtensions.KeyedService.cs share ~90% of their logic. The entire parameter resolution loop (matching dependsOn entries, resolving keyed vs non-keyed services) is duplicated. The only difference is the factory signature: Func<IServiceProvider, TTarget> vs Func<IServiceProvider, object?, TTarget>.
Suggested Fix
Extract the common resolution logic into a shared private method:
private static object[] ResolveConstructorArgs(
IServiceProvider sp, Dependency[] dependsOn, ParameterInfo[] parameters)
{
if (sp is not IKeyedServiceProvider keyed)
throw new NotSupportedException(...);
var args = new object[parameters.Length];
for (int i = 0; i < args.Length; i++)
{
var p = parameters[i];
var dep = Array.Find(dependsOn, d => d.ParameterName == p.Name);
if (dep != null)
{
args[i] = dep.T == Dependency.DependencyType.KeyedServices
? keyed.GetRequiredKeyedService(p.ParameterType, dep.Value)
: dep.Value;
}
else
{
args[i] = sp.GetRequiredService(p.ParameterType);
}
}
return args;
}
This would also help resolve the cognitive complexity warnings on both methods.
Description
DependsOnResolutionFunc<TTarget>andKeyedDependsOnResolutionFunc<TTarget>inServiceCollectionExtensions.KeyedService.csshare ~90% of their logic. The entire parameter resolution loop (matchingdependsOnentries, resolving keyed vs non-keyed services) is duplicated. The only difference is the factory signature:Func<IServiceProvider, TTarget>vsFunc<IServiceProvider, object?, TTarget>.Suggested Fix
Extract the common resolution logic into a shared private method:
This would also help resolve the cognitive complexity warnings on both methods.