C# 是否可以使用Microsoft.Extensions.DependencyInjection中的服务在同一类中使用同一接口的不同实现

C# 是否可以使用Microsoft.Extensions.DependencyInjection中的服务在同一类中使用同一接口的不同实现,c#,.net,dependency-injection,C#,.net,Dependency Injection,在这个 示例Temp2覆盖Temp1-> services.AddSingleton<ITemp1, Temp1>(); services.AddSingleton<ITemp1, Temp2>(); Temp1-> Temp1 : ITemp1 { void writeSomething(){ Console.WriteLine("First temp!")} } Temp2-> Temp2 : ITemp1 { void writeSometh

在这个 示例Temp2覆盖Temp1->

services.AddSingleton<ITemp1, Temp1>();
services.AddSingleton<ITemp1, Temp2>();
Temp1->

Temp1 : ITemp1
{
void writeSomething(){ Console.WriteLine("First temp!")}
}
Temp2->

Temp2 : ITemp1
{
void writeSomething(){ Console.WriteLine("Second temp!")}
}
然后我希望使用这样的类,其中我需要Temp1-使用接口实现项p1-类Temp1,Temp2-使用接口实现项p1-类Temp2。但遗憾的是,它们都将使用上次注册的服务的实现

class SomeClass
{
   private readonly ITemp1 _Temp1;
   private readonly ITemp1 _Temp2;

   public SomeClass(ITemp1 Temp1, ITemp1 Temp2)
   {
      this._Temp1 = Temp1;
      this._Temp2 = Temp2;
   }

}

您可以通过以下方式解决此问题:

services.AddSingleton<ITemp1, Temp1>();
services.AddSingleton<ITemp1, Temp2>();
var services = serviceProvider.GetServices<ITemp1>();
var temp2Serv = services.FirstOrDefault(x => x.GetType() == typeof(Temp2));
services.AddSingleton();
services.AddSingleton();
然后,无论何时,只要您想获得特定实例,都可以这样做:

services.AddSingleton<ITemp1, Temp1>();
services.AddSingleton<ITemp1, Temp2>();
var services = serviceProvider.GetServices<ITemp1>();
var temp2Serv = services.FirstOrDefault(x => x.GetType() == typeof(Temp2));
var services=serviceProvider.GetServices();
var temp2Serv=services.FirstOrDefault(x=>x.GetType()==typeof(Temp2));

您可以通过以下方式解决此问题:

services.AddSingleton<ITemp1, Temp1>();
services.AddSingleton<ITemp1, Temp2>();
var services = serviceProvider.GetServices<ITemp1>();
var temp2Serv = services.FirstOrDefault(x => x.GetType() == typeof(Temp2));
services.AddSingleton();
services.AddSingleton();
然后,无论何时,只要您想获得特定实例,都可以这样做:

services.AddSingleton<ITemp1, Temp1>();
services.AddSingleton<ITemp1, Temp2>();
var services = serviceProvider.GetServices<ITemp1>();
var temp2Serv = services.FirstOrDefault(x => x.GetType() == typeof(Temp2));
var services=serviceProvider.GetServices();
var temp2Serv=services.FirstOrDefault(x=>x.GetType()==typeof(Temp2));

您可能使用的选项之一是“命名注册”,DI的默认实现不支持该选项,但可以通过外部实现(如Autofac)轻松扩展该选项。使用Autofac,这可能看起来像

var autofacContainerBuilder = new ContainerBuilder();
autofacContainerBuilder.RegisterType<Temp1>().As<ITemp>().Named<ITemp>("Temp1").SingleInstance();
autofacContainerBuilder.RegisterType<Temp2>().As<ITemp>().Named<ITemp>("Temp2").SingleInstance();
            
然后在代码中的某个地方,您可能会注入命名实例,如:

     class MyClass
    {
        public MyClass([KeyFilter("temp1")]ITemp dep)
        {
            dep.SomeMethod();
        }
    }

或者您可以注入autofac提供的
ILifetimeScope
,并调用

scope.ResolveNamed<ITemp>("Temp1");
scope.ResolveNamed(“Temp1”);
有关详细信息,请参阅


Autofac不是唯一的外部DI提供程序,还有多个其他选项可以提供相同的功能

您可以使用的选项之一是“命名注册”,默认DI实现不支持该选项,但可以通过外部实现(如Autofac)轻松扩展该选项。使用Autofac,这可能看起来像

var autofacContainerBuilder = new ContainerBuilder();
autofacContainerBuilder.RegisterType<Temp1>().As<ITemp>().Named<ITemp>("Temp1").SingleInstance();
autofacContainerBuilder.RegisterType<Temp2>().As<ITemp>().Named<ITemp>("Temp2").SingleInstance();
            
然后在代码中的某个地方,您可能会注入命名实例,如:

     class MyClass
    {
        public MyClass([KeyFilter("temp1")]ITemp dep)
        {
            dep.SomeMethod();
        }
    }

或者您可以注入autofac提供的
ILifetimeScope
,并调用

scope.ResolveNamed<ITemp>("Temp1");
scope.ResolveNamed(“Temp1”);
有关详细信息,请参阅


Autofac不是唯一的外部DI提供程序,还有多种其他选择可能提供相同的功能

Temp1和Temp2实现在不同的地方使用。因此,你需要绑定到这些不同的地方。请提供更多信息。指定这些类型在何处使用以及如何使用。正如@AlexanderPetrov所说,没有看到如何在依赖它的类中使用这个接口,这个问题很难回答。到目前为止所显示的代码没有任何问题,所以这个问题确实需要回答一些问题。Temp1和Temp2实现在不同的地方使用。因此,你需要绑定到这些不同的地方。请提供更多信息。指定这些类型在何处使用以及如何使用。正如@AlexanderPetrov所说,没有看到如何在依赖它的类中使用这个接口,这个问题很难回答。到目前为止所显示的代码没有任何问题,所以这个问题确实需要回答一些问题因为我们已经在使用LINQ.Side注意:注册要同时使用的多个实现,或者注册要根据条件/上下文自动选择的多个实现,对于使用依赖项注入来说都不是“非常独特”的场景。决定从可能同时注册的几个接口返回哪个接口实现是容器的核心职责…@karljohansjögren感谢我第一次看到wat获得它!AlexeiLevenkov你是对的,我将删除我对matterOr的客观视图,只需
services.OfType().FirstOrDefault()因为我们已经在使用LINQ.Side注意:注册要同时使用的多个实现,或者注册要根据条件/上下文自动选择的多个实现,对于使用依赖项注入来说都不是“非常独特”的场景。决定从可能同时注册的几个接口返回哪个接口实现是容器的核心职责…@karljohansjögren感谢我第一次看到wat获得它!阿列克谢列文科夫你是对的,我会消除我对这件事的客观看法