是否应将依赖项存储到具有私有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; }
}
答案 0 :(得分:10)
我总是会推荐private readonly
个字段,只要不需要从对象外部访问依赖项。将对象视为"黑盒子"并尽可能少地放在他们的公共接口中。这种做法更好地称为 encapsulation principle 或信息隐藏,并且也适用于注入的依赖项:您公开的越少,您减少的类与您之间的紧密耦合就越多。你的班级'用户。
应该提到的另一个原则是对对象的行为建模:告诉,不要问。如果您需要完成某项任务,请让对象为您完成。它将在进程中使用其依赖项。询问属性和自己完成工作应该只是数据对象(DTO)的首选。
这也是首先使用构造函数注入的原因:如果将属性作为属性公开是最好的做法,那么每个人都会进行属性注入,因为这意味着更少的代码(我们不需要构造函数)然后)。
答案 1 :(得分:1)
这完全取决于您是否需要允许使用对象在使用对象的生命周期内更改依赖关系。
在构造函数上使用DI可以为你做两件事:
如果你想让你的对象保持不变,那么就可以使用公共getter和private setter了。然而事情并不总是那么简单 - 一个对象可能有很长的寿命,并且很容易有一个需要更改依赖关系的场景。
TL; DR:取决于此。当您编写大型应用程序时,您会发现需要混合使用方法 - 您将在ctor(s)中定义依赖关系,但对于其中一些应用程序,您需要使用该工具来更改它们在创建对象之后。
答案 2 :(得分:0)
我同意@Frank你必须将它保密,它更适合测试,它会为你提供更好的对象封装。
假设您的界面需要只访问Bar类,在这种情况下您的客户可以执行某些操作Bar.Dependency.BadMethodBurnTheDevice();