DI框架:如何避免不断地将注入的依赖项传递到链上,而不使用服务定位器(特别是使用Ninject)

Ted*_*Ted 14 c# dependency-injection ninject

我需要更多的帮助来"获得"像Ninject这样的DI框架如何超越基础.

拿Ninject样本:

class Samurai {
private IWeapon _weapon;

    [Inject]
    public Samurai(IWeapon weapon) {
      _weapon = weapon;
    }

    public void Attack(string target) {
      _weapon.Hit(target);
    }
 }
Run Code Online (Sandbox Code Playgroud)

没有DI框架(即上面的[Inject]引用),引用类看起来像:

class Program {
   public static void Main() { 
    Samurai warrior1 = new Samurai(new Shuriken());
    Samurai warrior2 = new Samurai(new Sword());
    warrior1.Attack("the evildoers");
    warrior2.Attack("the evildoers");
  }
}
Run Code Online (Sandbox Code Playgroud)

...你正在新的一切.是的,你已经删除了Samurai中的依赖项,但是现在你已经在链上向前迈进了一步.简单.

使用Ninject,你可以通过以下方式摆脱新的一切:

class Program {
  public static void Main() {
    IKernel kernel = new StandardKernel(new WarriorModule());
    Samurai warrior = kernel.Get<Samurai>();
    warrior.Attack("the evildoers");
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,这是我的困惑领域:没有使某种服务定位器能够有效地新建适用的内核和模块(即.IoC.TypeResolver.Get <>()),什么是a)最好的方法不必到处都是新内核(服务定位器引用到处都是?),b)更重要的是,当你有一个依赖于自己的依赖关系的大型长链时,你会把它带到一路注入极端我确信这是一种严重的反模式(朋友称之为"热土豆依赖注入"反模式).

换句话说,我认为DI框架魔术的一部分是你不必一直向上插入依赖关系(即你的第一个引用在其构造函数中包含10个参数,其中没有任何与任何事情,直到链条更进一步) - 这是我的混乱的魔力或解决方案,以便依赖关系不会不断被引用和链上升,或服务定位器引用遍布各处.

对我来说进一步混淆的是如果使用DI框架,那么处理引用类需要IList的场景的最佳方法是什么,IList通常会放在构造函数中(即新的ReferencedClass(myList)),除了在简单的情况下,如字符串数据库连接字符串,不会飞.只需创建一个属性并在新建/ DI Framework服务定位后设置它?即

var referencedClass = IoC.Get<IReferencedClass>();
referencedClass.MyList = myList;
Run Code Online (Sandbox Code Playgroud)

总而言之,我认为这是一个帖子,在我得到它之后我很可能会感到尴尬,但是现在,我已经在墙上试了几次,试图确定最好的方法.

Eri*_*ing 3

至于“烫手山芋”的依赖问题,这本不必发生。依赖注入框架会为您处理这个问题。

例如,如果 Class1 依赖于 Class2,而 Class2 依赖于 Class3,则无需将 Class3 注入到 Class1 中以适应 Class2 依赖关系。当您请求 Class1 时,内核将为您沿着依赖关系链走下去,并自动解析下游依赖关系(只要所有正在运行的类都已在内核中注册)。

Class1 取决于 Class2 取决于 Class3

Class1的构造函数根本不需要提及Class3。

至于第二个问题,如何或是否适应取决于框架。使用 Ninject,我认为您可以使用Bind().To().WithConstructorArgument()语法向构造函数提供新的 List 项。