无法从Microsoft.Extensions.DependencyInjection.IServiceProvider获取具体类型

时间:2018-05-22 17:30:45

标签: c# asp.net-core dependency-injection .net-core

我正在使用Microsoft.Extensions.DependencyInjection服务注册接口(servicesBuilder.AddSingleton<IFooRepository, FooInMemoryRepository>(); ),如下所示:

services.GetRequiredService<IFooRepository>()

当我解决依赖关系时,几乎完全我对具体类型不可知:

FooInMemoryRepository

在哪种情况下一切正常。但是在极少数情况下我需要具体实现(services.GetRequiredService<FooInMemoryRepository>() ),所以我想直接解决这个问题。我试着打电话给那个

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

然而,这引发了一个例外:

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";
}

示例代码(LINQPad):

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

输出:

IFooRepository

如果我所有注册的IFooRepository个实例,我确实得到了两者。如果我只要求InvalidOperationException我就会注册 last 具体实现。如果我要求具体实施,我会得到doc.get("_id");

是否可以从依赖注入器中解析具体类型,或者我是否必须始终解析所有这些类型,找到我想要的那个并将其转换为具体类型?

1 个答案:

答案 0 :(得分:1)

是的,你可以,但你必须明确注册。

除了

servicesBuilder.AddSingleton<IFooRepository, FooInMemoryRepository>();
servicesBuilder.AddSingleton<IFooRepository, FooOtherRepository>();

你还需要

servicesBuilder.AddSingleton<FooInMemoryRepository>();
servicesBuilder.AddSingleton<FooOtherRepository>();