`IServiceProviderIsService`'s behavior is unsound for constrained open generics
- Dominant language
- C#
- Stars
- 18.3k
- Forks
- 5.6k
- PR merge metrics
- PR metrics pending
Description
### Description
There is a circumstance in which `IServiceProviderIsService` returns `true` even though the container would NOT, in fact, resolve any services for the specified `Type`. This defeats the point of `IServiceProviderIsService` in such cases.
### Reproduction Steps
Consider the following scenario:
```cs
using Microsoft.Extensions.DependencyInjection;
var services = new ServiceCollection();
// services.AddScoped(typeof(IFoo<>), typeof(FooForEverything<>));
services.AddScoped(typeof(IFoo<>), typeof(FooForSpecials<>));
var sp = services.BuildServiceProvider();
var isService = sp.GetRequiredService();
Console.WriteLine($"IFoo has services? {isService.IsService(typeof(IFoo))}");
Console.WriteLine($"IFoo has services? {isService.IsService(typeof(IFoo))}");
using var scope = sp.CreateScope();
var one = scope.ServiceProvider.GetServices>();
Console.WriteLine($"For IFoo: ({one.Count()}) {string.Join(", ", one)}");
var two = scope.ServiceProvider.GetServices>();
Console.WriteLine($"For IFoo: ({two.Count()}) {string.Join(", ", two)}");
public interface IFoo;
public sealed class FooForEverything : IFoo;
public sealed class FooForSpecials : IFoo
where T : ISpecial;
public interface ISpecial;
public sealed class Special : ISpecial;
```
### Expected behavior
One would expect that since the line adding `FooForEverything<>` to the DI container has been commented out, and thus no services will be returned from `GetServices>`, that `isService.IsService(typeof(IFoo))` would return `false`. But it returns `true`, which is wrong.
And notably, this is how it works in AutoFac.
### Actual behavior
`isService.IsService(typeof(IFoo))` returns `true`, but it's lying.
This will be the console output if you ran the program above:
```
IFoo has services? True
IFoo has services? True
For IFoo: (1) FooForSpecials`1[Special]
For IFoo: (0)
```
Notice how `IFoo has services? True` and `For IFoo: (0)` are contradictory.
### Regression?
_No response_
### Known Workarounds
_No response_
### Configuration
_No response_
### Other information
cc @davidfowl
Contributor guide
Assessment
This issue has not been assessed yet.