问题描述
|
我正在为项目使用IoC和DI。
但是我想知道是否具有以下优点是一种好习惯:
private readonly IMyService myservice;
作为服务使用者的类中的字段。该字段在构造函数中设置。
我确定我在某个地方看到过这个东西,并且已经接好了。
但是我也看到:
private IMyService myservice;
似乎足够了。注入的服务接口是否有一个只读字段?有什么优势?
解决方法
我认为使用
readonly
关键字是正确构造构造函数注入的核心部分。
public class MyClass
{
private readonly IMyService myservice;
public MyClass(IMyService myservice)
{
if (myservice == null)
{
throw new ArgumentNullException(\"myservice\");
}
this.myservice = myservice;
}
}
技术上,the2 nor关键字和Guard子句都不是实现构造函数注入的必需项。但是,它们都有助于加强类的不变性。这就是封装的全部意义所在。
, 它是一个接口的事实是无关紧要的。在字段上应用readonly
修饰符可防止您(或其他人)在构造对象之后更改其值。它只能在构造函数中分配。
, “ 2”字段表示只能将其写入ctor中。完成此操作后,将无法更改或销毁引用。这对于初始化状态和强制不变性非常有用。
, 在字段上具有readonly
的优点是它清楚地声明了该字段在包含实例的生存期内不会更改。在许多情况下,这使得对给定方法的行为进行推理变得更加容易。例如
void Method() {
var marker = myservice.StartOperation();
try {
SomeOtherMethod();
} finally {
myservice.StopOperation(marker);
}
}
假设StartOperation
和StopOperation
是必须在给定的IMyService
实例上成对调用的方法。当myservice
是readonly
字段时,您只能查看此功能,并且对达成此合同具有高度的信心。
但是,如果不是readonly
,则必须立即怀疑SomeOtherMethod
以及从该函数传递调用的所有其他方法。如果其中任何一个可以突然重置reset12ѭ字段,那么您将违反合同并最终出现一些非常细小的错误。
, 这是readonly关键字的文档。
当应用于类中的字段时,“ 2”向读者表明“此字段在此实例的生存期内不会更改。”这对于依赖项是非常有用的信息,在构造函数中接收到它们后,它们不打算更改。 。
错误地尝试更改依赖项会导致编译时错误,提醒您或其他任何人正在修改不应更改已注入依赖项的类。与省略readonly
关键字和以后由于重新分配而不得不跟踪错误相比,这是一种更容易检测和修复的情况。
简而言之,是的,如果您在构造对象后不进行更改,则声明“ 2”是个好习惯,因为它将阻止所有将来的作者犯该错误。