Reputation: 4923
I am registering an interface (IFoo
) with the Microsoft.Extensions.DependencyInjection
service as follows:
servicesBuilder.AddSingleton<IFooRepository, FooInMemoryRepository>();
Almost exclusively I am agnostic on the concrete type when I resolve the dependency as such:
services.GetRequiredService<IFooRepository>()
In which case everything works fine. However in rare instances I need the concrete implementation (FooInMemoryRepository
) so I want to resolve that directly. I tried calling that
services.GetRequiredService<FooInMemoryRepository>()
However this throws an exception:
System.InvalidOperationException: No service for type 'UserQuery+FooInMemoryRepository' has been registered.
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at UserQuery.Main() in C:\Users\User\AppData\Local\Temp\LINQPad5\_ntmafjyh\query_eecehy.cs:line 37
Sample code (LINQPad):
void Main()
{
var servicesBuilder = new ServiceCollection();
servicesBuilder.AddSingleton<IFooRepository, FooInMemoryRepository>();
servicesBuilder.AddSingleton<IFooRepository, FooOtherRepository>();
var services = servicesBuilder.BuildServiceProvider();
try
{
var foos = services.GetServices<IFooRepository>();
foreach(var foo in foos)
{
Console.WriteLine(foo.SomeMethod());
}
var ifoo = services.GetRequiredService<IFooRepository>();
Console.WriteLine(ifoo.SomeMethod());
var inMemoryRepo = services.GetRequiredService<FooInMemoryRepository>();
Console.WriteLine(inMemoryRepo.SomeMethod());
}
catch(InvalidOperationException ioex)
{
Console.WriteLine(ioex.ToString());
}
}
// Define other methods and classes here
public interface IFooRepository
{
string SomeMethod();
}
public class FooInMemoryRepository : IFooRepository
{
public string SomeMethod() => "InMemory Foo";
}
public class FooOtherRepository : IFooRepository
{
public string SomeMethod() => "Other Foo";
}
Output:
InMemory Foo
Other Foo
Other Foo
System.InvalidOperationException: No service for type 'UserQuery+FooInMemoryRepository' has been registered.
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at UserQuery.Main() in C:\Users\TheGreatCO\AppData\Local\Temp\LINQPad5\_ntmafjyh\query_jcpvdk.cs:line 45
If I get all of the IFooRepository
instances registered, I do get both. If I ask for just IFooRepository
I get the last concrete implementation registered. If I ask for a specific concrete implementation, I get an InvalidOperationException
.
Is it possible to resolve the concrete type from the dependency injector here or must I always resolve all of them, find which one I want and cast it to the concrete type?
Upvotes: 1
Views: 1582
Reputation: 64307
Yes you can, but you have to register it explicitly.
In addition to
servicesBuilder.AddSingleton<IFooRepository, FooInMemoryRepository>();
servicesBuilder.AddSingleton<IFooRepository, FooOtherRepository>();
you also need
servicesBuilder.AddSingleton<FooInMemoryRepository>();
servicesBuilder.AddSingleton<FooOtherRepository>();
Upvotes: 1