c# - DI Framework : how to avoid continually passing injected dependencies up the chain, 且未使用服务定位器(特别是使用 Ninject)

标签 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);
    }
 }

如果没有 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");
  }
}

...您更新所有内容的地方。是的,您已经删除了 Samurai 中的依赖项,但现在您在链条上更进一步获得了依赖项。简单。

使用 Ninject,您可以通过以下方式摆脱更新所有内容:

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

然而,这是我感到困惑的地方:如果没有制作某种服务定位器来有效地更新适用的内核和模块(即 .IoC.TypeResolver.Get<>()),什么是 a)不必在任何地方都更新内核的最佳方法(到处都引用服务定位器?),以及 b) 更重要的是,当你有一个很大的长链并且有自己的依赖关系时,你会把它带到传递注入(inject)的极端一路向上,我确信这是一个严重的反模式(一个 friend 称之为“烫手山芋依赖注入(inject)”反模式)。

换句话说,我认为 DI 框架的神奇之处在于,您不必一直在链上插入依赖项(即,您的第一个引用在其构造函数中包含 10 个参数,其中没有任何参数做任何事,直到沿着链更远)- 魔法 或解决我的困惑的方法在哪里,这样依赖项就不会不断地在链上向上引用,或者服务定位器引用遍布各处.

如果使用 DI 框架,让我更加困惑的是,如果使用 DI 框架,那么处理引用类需要 IList 的情况的最佳方法是什么,该 IList 通常会放在构造函数中(即 new ReferencedClass(myList)) ,除了在像字符串数据库连接字符串这样的简单情况下,不会飞。 new up/DI Framework service locating 后做一个属性设置就可以了? IE。

var referencedClass = IoC.Get<IReferencedClass>();
referencedClass.MyList = myList;

总而言之,我认为这是一个我收到后可能会感到尴尬的帖子,但现在,我已经多次撞墙试图确定最佳方法。

最佳答案

至于“烫手山芋”的依赖问题,这倒不一定发生。依赖注入(inject)框架会为你处理这个。

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

Class1 depends on Class2 depends on Class3

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

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

关于c# - DI Framework : how to avoid continually passing injected dependencies up the chain, 且未使用服务定位器(特别是使用 Ninject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1993273/

相关文章:

c# - OutOfMemoryException 与 gcAllowVeryLargeObjects

c# - 在 .NET Core 中使用 FluentValidation 和依赖注入(inject)

ef-code-first - 使用 Mehdime.Entity AmbientDbContextLocator 实例化 DbContext 派生类

c# - protobuf.net De-Serializer 无限期等待

c# - 没有外部登录提供程序的 ASP.NET Core MVC 2.2 登录

c# - IServiceRepository 中的存储库模式 IRepository<T>

c# - 有没有办法传播多次注入(inject)?

dependency-injection - ActionFilterAttribute ninject 注入(inject) - DbContext 已被释放

c# - Parse.com 绑定(bind)到 ListView ItemSource 如何

angularjs - 是否有某些文件不应该包含在 Angular 2 的桶文件中和/或导入的顺序很重要?