Ninject WCF 扩展 TimeService 示例如何工作?
我有一个 .Net 4.0 WCF 服务,我正在尝试为其设置 ninject。我下载了 ninject 的 WCF 扩展 并查看了 TimeService 示例。一切看起来都很简单,但是我看不到 ninject 如何正确完成其工作,因为有一个无参数构造函数手动注入依赖项。
public TimeService()
: this(new SystemClock())
{
}
public TimeService( ISystemClock systemClock )
{
_systemClock = systemClock;
}
据我了解,这段代码永远不会使用 ninject 绑定。如果我不提供任何参数,第一个构造函数将调用第二个构造函数。在测试时,我传入模拟对象,第二个构造函数将被调用。我对 WCF 和 ninject 都很陌生,所以如果我遗漏了任何明显的东西,我深表歉意!
谁能解释一下吗?
谢谢
I have a .Net 4.0 WCF service that I'm trying to setup ninject for. I downloaded the WCF extension for ninject and had a look through the TimeService example. Everything looks simple enough, however I can't see how ninject is doing its job correctly as there is a parameter-less constructor manually injecting the dependency.
public TimeService()
: this(new SystemClock())
{
}
public TimeService( ISystemClock systemClock )
{
_systemClock = systemClock;
}
As far as I understand this code will never use ninject binding. The first constructor will call the second constructor if I don't provide any params. When in testing and I pass in my mock object the second constructor will be called. I'm pretty new to both WCF and ninject so apologies if I am missing anything obvious!
Can anyone explain?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
默认情况下,Ninject 将选择参数数量最多的构造函数,它有足够的绑定信息来填充。因此,如果 Ninject 模块能够提供 ISystemClock 实现,Ninject 将更喜欢第二个构造函数。
当您想要允许注入依赖项,但在没有特定依赖项时仍然有一个逻辑默认值可以依靠时,通常会使用此处显示的模式。正如您所指出的,您可以在单元测试时提供自己的 ISystemClock 模拟,这为您提供了确定性测试的优势。同样,如果您出于某种原因想要提供自定义 ISystemClock 实现,您可以使用匹配的绑定来设置 Ninject 模块。
另一方面,对于大多数用途,库存 SystemClock 实现可能是最好使用的实现,因此,与其强制您设置 ISystemClock 绑定以使类正常运行,不如提供一个备用构造函数,该构造函数使用 SystemClock 作为默认实现。如果您没有为 ISystemClock 服务指定绑定,Ninject 将依赖此构造函数。
编辑
在这种特殊情况下,它没有运行的原因是 TimeService 类上的以下属性:
我不完全理解这里发生了什么,但它在某种程度上阻止了 Ninject用于创建服务。如果您注释掉这一行,它应该按预期工作。
By default, Ninject will choose the constructor that has the largest number of parameters, which it has enough binding information to fill. So if the Ninject module is capable of providing an ISystemClock implementation, Ninject will prefer the second constructor.
The pattern you're showing here is often used when you want to allow for injected dependencies, but still have a logical default to fall back on in the absence of a specific dependency. As you pointed out, you can provide your own ISystemClock mock when unit testing, which gives you the advantage of deterministic testing. Likewise, if you had some reason to want to provide a custom ISystemClock implementation, you could set up your Ninject modules with a matching binding.
On the other hand, for most purposes the stock SystemClock implementation is probably the best one to use, so rather than forcing you to set up an ISystemClock binding in order for the class to even function, an alternate constructor is provided which uses the SystemClock as a default implementation. Ninject will fall back on this constructor if you haven't specified a binding for the ISystemClock service.
Edit
In this particular case, the reason it's not running is due to the following attribute on the TimeService class:
I don't fully understand what all is going on here, but it is somehow preventing Ninject from being used to create the service. If you comment out this line, it should work as expected.