注入的依赖项是公共可访问还是私有?

是否应将依赖项存储到具有私有setter和public 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; } } 

我总是会建议private readonly字段,只要不需要从对象外部访问依赖项。 将您的对象视为“黑匣子”,并尽可能少地放在他们的公共界面中。 这种做法更好地称为封装原则信息隐藏 ,也适用于注入的依赖关系:暴露的越少,您减少的类与类的用户之间的紧密耦合就越多。

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

这也是首先使用构造函数注入的原因:如果将属性作为属性公开是最佳实践,则每个人都会进行属性注入,因为这意味着更少的代码(我们不需要构造函数)。

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

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

  • 它正在定义一个合同,说“这个类需要这个特定的依赖关系才能运行”
  • 它允许您轻松地操作注入不同实现所使用的依赖项(即在unit testing时注入模拟实现,或者您在使用MVVM时有一个可以采用任何几个视图模型的视图等)

如果你想让你的对象保持不变,那么就可以使用公共getter和私有setter了。 然而事情并不总是那么简单 – 一个对象可能有很长的寿命,并且很容易有一个需要更改依赖关系的场景。

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

我同意@Frank你必须将它保密,它更适合测试,它会给你一个更好的对象封装。

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