私有只读接口 – 它是多余的吗?
我正在为我的项目使用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; } }
从技术上讲, readonly
关键字和Guard子句都不需要实现构造函数注入。 但是,它们都有助于加强class级的不变量。 这就是封装的全部内容 。
事实上它是一个界面是无关紧要的。 在字段上应用readonly
修饰符会阻止您(或其他人)在构造对象后更改其值。 它只能在构造函数中指定。
readonly
字段意味着它只能写在ctor中。 一旦完成,就无法更改或销毁引用。 它对于初始化状态和强制执行不变性非常有用。
拥有readonly
on the field的优点是它清楚地声明该字段在包含实例的生命周期内不会改变。 在许多情况下,这使得更容易推断给定方法的行为。 例如
void Method() { var marker = myservice.StartOperation(); try { SomeOtherMethod(); } finally { myservice.StopOperation(marker); } }
假设StartOperation
和StopOperation
是必须在给定的IMyService
实例上成对调用的方法。 当myservice
是一个readonly
字段时,您只能查看此function,并且对满足此合同具有高度的信心。
但是,如果它不是readonly
你必须立即怀疑SomeOtherMethod
和从该函数传递调用的所有其他方法。 如果他们中的任何一个突然重置myservice
字段你将违反合同并最终得到一些非常微妙的错误。
以下是readonly关键字的文档。
当应用于类中的字段时, readonly
向读者指示“此字段在此实例的生命周期内不会更改”。 这对依赖项非常有用,在构造函数中接收它们之后无意更改。
错误的尝试更改依赖项会导致编译时错误,提醒您或其他任何人正在修改注入依赖项的类不应更改。 这比检测和修复更容易,而不是省略readonly
关键字,后来由于重新分配而不得不追踪错误。
简而言之,是的,如果你在构造对象之后没有改变它,那么最好只声明一些东西,因为它会让所有未来的作者都不会犯这个错误。