【问题标题】:How do I properly use Dependency Injection?如何正确使用依赖注入?
【发布时间】:2012-05-27 12:54:39
【问题描述】:

简单案例: 我有一个用于记录消息的界面,如下所示:

public interface ILogger
{
   void Log(string message);
}

也许三个不同的类实现了这个接口。

现在,我可以在一个地方写下 DI 行,类似于:

kernel.Bind<ILogger>().To<ConsoleLogger>();

我的问题是,如何在许多类中使用该接口,而不是通过构造函数注入每个人。因为我们可以有很多我们想要使用的不同接口,并且在该类构造函数上的声明可能会很混乱。

【问题讨论】:

  • 你应该使用构造函数注入。其他一切都是代码味道。

标签: c# oop dependency-injection ninject


【解决方案1】:

在构造函数中注入过多的项是代码异味。这通常意味着您的班级正在扮演多个角色。 single responsiblity principle 表示每个类应该只有一个完全封装在类中的目的。

【讨论】:

  • 我觉得,有小误会。如果我在这个类中创建这个日志记录“引擎”作为一个函数,SRP 可能会被破坏。但我只想在某些类中使用这个 ILogger。我认为,德米特里是对的。
  • 如果您需要在许多类中注入 ILogger,您可能已经违反了 SRP,因为日志记录是一个横切关注点,并且在许多情况下应该使用拦截或(甚至更好)使用装饰器进行建模.
  • @Steven 你能提供样品吗?
  • @Maniekb:看看这个问题(和答案):stackoverflow.com/questions/9892137/…
【解决方案2】:

在依赖注入中,在遗留场景之外使用属性注入被认为是糟糕的形式。通过属性注入一个值表明它是可选的,因此并不是真正的依赖。

如果您的类型具有大量的构造函数依赖项,这可能表明您需要进行一些重构。也许某些类型可以一起使用,并且可以重构为它们自己的组件。无论哪种方式,如果您使用的是 IoC 框架(例如 Ninject),那么一个类型需要多少个构造函数参数真的很重要吗?无论如何,容器都会为您进行注射。

【讨论】:

  • +1 用于突出构造函数和属性之间的意图差异。 -1 用于继续维护/测试肆无忌惮的参数注入的痛苦。
【解决方案3】:

虽然@LukeMcGregor 所说的通常是正确的,但 Logger 看起来像是一个跨领域问题,如果您不想用 ILogger 污染每个构造函数,也可以通过AOP 解决。 Ninject 似乎通过ninject.extensions.interception 支持AOP。

【讨论】:

    【解决方案4】:

    您可以在类中实现ILogger Logger { get; set;} 属性,并使用大多数 IoC 容器支持的属性注入功能。

    【讨论】:

      猜你喜欢
      • 2020-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多