简体   繁体   English

IOC / DI有2个实现相同接口的类

[英]IOC/DI with 2 classes that implement same interface

I am getting confused with the scenario of 2 classes implementing the same interface and Dependency Injection. 我对实现相同接口和依赖注入的2个类的场景感到困惑。

public interface ISomething
{
  void DoSomething();
}

public class SomethingA : ISomething
{
  public void DoSomething()
  {

  }
}

public class SomethingAB : ISomething
{
  public void DoSomething()
  {

  }
}

public class Different
{
  private ISomething ThisSomething;

  public Different(ISomething Something)
  {  
    ThisSomething = Something;
  }
}

I have seen online examples say that this is valid but you would only use one class at a time. 我已经看到在线示例说这是有效的,但你一次只能使用一个类。 So if the app is running at SiteA you tell your IOC to use SomethingA but if its at SiteB you tell it to use SomethingAB. 因此,如果应用程序在SiteA运行,您告诉您的IOC使用SomethingA,但如果它在SiteB,您告诉它使用SomethingAB。

Is it considered bad practice therefore to have one app that has 2 classes that implement 1 interface and for it to try to use both classes? 因此,有一个应用程序有2个类实现1个接口,并尝试使用这两个类,这被认为是不好的做法吗? If its not how do you tell the IOC which class to use in the relevant circumstance? 如果不是你怎么告诉国际奥委会在相关情况下使用哪个班级?

UPDATE: To explain it better I will use Ninject's example: 更新:为了更好地解释它,我将使用Ninject的例子:

public class Samurai 
{
    private IWeapon Weapon;

    public Samurai(IWeapon weapon) 
    {
        this.Weapon = weapon;
    }
}

public class Sword : IWeapon
{
...
}

public class Gun : IWeapon
{
...
}

public class WarriorModule : NinjectModule
{
    public override void Load() 
    {
        this.Bind<IWeapon>().To<Sword>();
        this.Bind<IWeapon>().To<Gun>();  //Just an example
    }
}

So now you have 2 classes that use IWeapon. 所以现在你有两个使用IWeapon的类。 Depending on something or a context in your app you want Samurai to have a Sword sometimes or a Gun at other points. 根据您应用中的某些内容或背景,您希望Samurai有时会使用剑或在其他点使用枪。 How do you make this happen? 你是怎么做到这一点的? How do you handle that "if" scenario?? 你如何处理“if”场景?

I don't think that this is a bad practice in the general case. 我不认为这在一般情况下是不好的做法。 There are situations where you could need different implementations of the same interface inside the same application and based on the context use one or another implementation 在某些情况下,您可能需要在同一个应用程序中使用相同接口的不同实现,并且基于上下文使用一个或另一个实现

As far as how to configure your DI to enable this scenario, well, it will depend on your DI of course :-) Some might not support it, others might not, others might partially support it, etc.. 至于如何配置你的DI以启用这个场景,当然,它将取决于你的DI :-)有些人可能不支持它,其他人可能不支持,其他人可能部分支持它等等。

For example with Ninject , you could have the following classes: 例如,使用Ninject ,您可以拥有以下类:

public interface ISomething
{
}

public class SomethingA : ISomething
{
}

public class SomethingB : ISomething
{
}

public class Foo
{
    public Foo(ISomething something)
    {
        Console.WriteLine(something);
    }
}

public class Bar
{
    public Bar(ISomething something)
    {
        Console.WriteLine(something);
    }
}

and then use named bindings when configuring the kernel: 然后在配置内核时使用命名绑定:

// We create the kernel that will be used to provide instances when required
var kernel = new StandardKernel();

// Declare 2 named implementations of the same interface
kernel.Bind<ISomething>().To<SomethingA>().Named("somethingA");
kernel.Bind<ISomething>().To<SomethingB>().Named("somethingB");

// inject SomethingA into Foo's constructor
kernel.Bind<Foo>().ToSelf().WithConstructorArgument(
    "something", ctx => ctx.Kernel.Get<ISomething>("somethingA")
);

// inject SomethingB into Bar's constructor
kernel.Bind<Bar>().ToSelf().WithConstructorArgument(
    "something", ctx => ctx.Kernel.Get<ISomething>("somethingB")
);

Now when you request an instance of Foo it will inject SomethingA into it its constructor and when you request an instance of Bar it will inject SomethingB into it: 现在当你请求一个Foo实例时,它会将SomethingA注入其构造函数中,当你请求一个Bar实例时,它会将SomethingB注入其中:

var foo = kernel.Get<Foo>();
var bar = kernel.Get<Bar>();

i worked with Unity and spring in this context and i think that interest lies in having a weak coupling between packages, ie classes, the ability to change service or point of entry is a consequence of the ioc. 在这种情况下我和Unity一起工作并且我认为感兴趣在于包之间的弱耦合,即类,改变服务或进入点的能力是ioc的结果。

ioc provides flexibility in the use of service, or from the time the services implement the same interface, ioc提供了服务使用的灵活性,或者从服务实现相同接口的时候开始,

If Utilize Service A Service B and Service is in the service package A and package B is in B. Package A has no reference on the package b, but the service A has a reference on the package containing the interfaces. 如果使用服务A服务B和服务在服务包A中,而包B在B中。包A没有对包b的引用,但服务A在包含接口的包上有引用。 Therefore we conclude that we have a weak coupling between package A and package b. 因此,我们得出结论,我们在包A和包b之间存在弱耦合。

Having multiple implementations mapped to the same interface isn't really bad practice, but it isn't he most common usage pattern. 将多个实现映射到同一个接口并不是很糟糕的做法,但它并不是最常见的使用模式。

You didn't specify a specific DI tool, but if you use Unity, you can do this with named instances. 您没有指定特定的DI工具,但如果您使用Unity,则可以使用命名实例执行此操作。 See here: Unity - how to use multiple mappings for the same type and inject into an object 请参阅此处: Unity - 如何对同一类型使用多个映射并注入对象

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ServiceStack IoC/DI:在容器中注册类 - 如何注册所有实现特定接口的类 - ServiceStack IoC/DI: Registering classes in the Container - how to register all that implements a specific interface 在类之间交换数据 - DI、IoC - Exchanging data between classes - DI, IoC IoC / DI:当存在同一接口的多个实现时,如何注入特定实例 - IoC/DI: How to inject specific instance when there are multiple implementations of same interface 2个类实现相同的接口,重复的代码 - 2 classes implement same interface, duplicated code 如何获得实现相同接口的所有类? - How to get all classes that implement same interface? 带ninject的DI,IoC绑定(到IEnumerable的绑定接口 <T> 方法) - DI, IoC Bindings with ninject (Binding Interface to IEnumerable<T> method) 制作自定义IoC-如何实现具有范围的DI? - Making Custom IoC - How to Implement DI That Has Scope? 不同的类必须以完全相同的方式实现接口方法 - Different classes have to implement an interface method in exactly the same way 使用Ninject注入实现相同接口的不同类 - Inject different classes that implement the same interface using Ninject 检索实现多个相同通用接口的类的唯一列表 - Retrieve unique list of classes that implement multiple of the same generic interface
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM