【问题标题】:Should injected dependencies be publicly accessible or private?注入的依赖项应该是可公开访问的还是私有的?
【发布时间】:2015-01-08 12:16:08
【问题描述】:

是否应该使用私有 setter 和公共 getter 将依赖项存储到私有字段或属性?这适用于构造函数 DI。

需要明确的是,在属性示例中,除非有意义,否则我不希望将它们添加到随附的接口中 - 即它们仅在实现类型中可见:

interface IFoo {
  void DoSomething();
}

class Foo : IFoo {
  private readonly IService dependency;
  public Foo(IService dependency) {
    this.dependency = dependency;
  }
}

class Bar : IFoo {
  public Foo(IService dependency) {
    this.Dependency = dependency;
  }

  public IService Dependency { get; private set; }
}

【问题讨论】:

    标签: c# .net design-patterns dependency-injection


    【解决方案1】:

    我总是推荐private readonly 字段,只要不需要从对象外部访问依赖项。将您的对象视为“黑匣子”,并尽可能少地放在它们的公共接口中。这种做法更好地称为 encapsulation principle信息隐藏,也适用于注入的依赖项:暴露的越少,就越能减少类和类之间的紧密耦合' 用户。

    另一个应该提到的原则是建模对象的行为:告诉,不要问。如果您需要完成某事,请让对象为您完成。它将在此过程中使用其依赖项。请求属性并自己完成工作应该只是数据对象 (DTO) 的首选。

    这也是首先使用构造函数注入的原因:如果将依赖项暴露为属性是最佳实践,那么每个人都会做属性注入,因为这意味着更少的代码(那时我们不需要构造函数) .

    【讨论】:

      【解决方案2】:

      这完全取决于您是否需要允许消费对象在被消费对象的生命周期内更改依赖关系。

      在构造函数上使用 DI 为你做了两件事:

      • 它在定义一个契约,说“这个类需要这个特定的依赖来运行”
      • 它允许您通过注入不同的实现(即在单元测试时注入模拟实现,或者您的视图可以在使用 MVVM 时采用多个视图模型中的任何一个等)来轻松操作所使用的依赖项。

      如果您希望保持对象不可变,那么公共 getter 和私有 setter 是您的最佳选择。然而事情并不总是那么简单——一个对象可能有很长的生命周期,很容易出现需要更改依赖关系的场景。

      TL;DR: 视情况而定。当您编写大型应用程序时,您会发现您需要混合您的方法 - 您将在 ctor(s) 中定义依赖项,但对于其中一些,您需要在创建对象后更改它们的工具.

      【讨论】:

        【解决方案3】:

        我同意 @Frank 的观点,您必须将其保密,这样更适合测试,并且可以为您提供更好的对象封装。

        假设您有一个只需要访问 Bar 类的接口,在这种情况下您的客户可以做某事Bar.Dependency.BadMethodBurnTheDevice();

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-11-04
          • 1970-01-01
          • 1970-01-01
          • 2011-09-12
          • 2018-03-17
          • 2018-06-15
          • 1970-01-01
          相关资源
          最近更新 更多