正确使用依赖注入

proper use of dependency injection

我一直在使用依赖注入,我注意到在构造函数(你正在注入的)中,参数通常是一个接口或一个基class。我想我明白参数不是接口就是基数的原因class。但是,我意识到有时我尝试注入的实际 class/object 可以使用接口或基础 class 都不应该拥有的方法(因为只有实际的 class/object 我'm 实例化应该有那个方法)。但如果是这样的话,这意味着如果注入的参数是接口或基 class,我将无法调用该方法。我是否应该只创建另一个接口来包含我想要在我尝试实例化的实际 class/object 上使用的方法?我有一个例子:

public interface IAnimal
{
   void Eat();
}

public abstract class Mammals : IAnimal
{
   public void Eat()
   {
      //eating code
   }

   public void Sleep()
   {
      //sleep code
   }
}

public class Whale : Mammals
{
   public void Swim()
   {
      //swim code
   }
}

public class Dog : Mammals
{
   public void Run()
   { 
      //run code
   }

}

//Injecting here
public class Class1
{
    private readonly Mammals x;
     public Class1(Mammals x)
     {
         this.x = x;
     }

     public class Method1()
     {
         x.Eat();
         x.Sleep();

         //I can't call swim() unless I do below:
         //Whale y = x;
         //y.Swim();
     }

}

我一直认为使用 Interface 或 base class(在依赖注入中)可以让你编写更清晰的代码,因为如果我决定更改我正在注入的 class/object,我不会不必对代码进行任何更改,因为我注入的任何对象都将具有接口或具有基础 class。但是如果我添加允许我使用 Swim() 的代码,然后决定注入 Dog class,我将不得不更改代码以改为使用 运行()。我试图完全理解依赖注入和使用它的正确方法。我注意到我的代码确实因此看起来更干净了。我应该如何处理上述代码的问题?

如果这个class真的是在处理任何一种哺乳动物,而你想让它们中的一些游泳,那么你可以测试注入的对象是否实现了ISwim。

例如(哺乳动物作为ISwim)?.Swim();

这不完全是依赖注入问题,而是设计问题。 依赖注入用于解耦,并允许更好的单元测试帮助将客户端与设计更改或实现的影响隔离开来。 至于你的问题,你可以调用 Move(),这应该与所有哺乳动物相关,或者按照上面的建议使用 iwatermammals。