MUG*_*G4N 4 c# dependencies dependency-injection ninject inversion-of-control
问题
我有一些问题需要了解我的代码中何时何地应该使用像Ninject这样的依赖注入器.
码
比方说,我们有以下代码:
//WITHOUT NINJECT:
IMailSender mailSender = new MockMailSender();
//WITH NINJECT:
IMailSender mailSender = kernel.Get<IMailSender>();
Run Code Online (Sandbox Code Playgroud)
这个不是依赖注入,所以在这种情况下使用Ninject是否有意义?
另一个例子显示了如何使用依赖注入器使我的代码变得非常混乱:
public void CalculateRevenueRecognitions(IContract contract)
{
//WITH NINJECT
var kernel = new StandardKernel(new DefaultModule());
var arguments = new List<IParameter>
{
new ConstructorArgument("amount",contract.Revenue),
new ConstructorArgument("date", contract.WhenSigned)
};
contract.AddRevenueRecognition(kernel.Get<IRevenueRecognition>(arguments.ToArray()));
//WITHOUT NINJECT:
contract.AddRevenueRecognition(new RevenueRecognition(contract.Revenue, contract.WhenSigned))));
}
Run Code Online (Sandbox Code Playgroud)
题
我什么时候应该使用依赖注入器?
什么时候不应该使用依赖注入器?
基本前提是不依赖于具体的类(就像你说的新的具体类)和注入实现(通过接口).这取决于您正在执行的具体任务以及在什么条件下(Windows服务,WCF服务,Asp.Net),但在大多数情况下,您有一个接口,其中包含您希望公开公开的所有方法,如此
public interface IBar {
void DoStuff();
}
Run Code Online (Sandbox Code Playgroud)
然后,然后使用Ninject将这些绑定到特定的类,即
Bind<IBar>().To<BarClass>();
Run Code Online (Sandbox Code Playgroud)
所以在启动时,Ninject会获得配置的实现.这方面的优点是您的实现已配置,因此只要它实现接口,就可以很容易地交换到另一个实现.所以如果你现在想要使用另一个类而不是BarClass,你可以重新绑定它,即
Bind<IBar>().To<NewBarClass>();
Run Code Online (Sandbox Code Playgroud)
因此,只要您需要使用此NewBarClass,就可以像这样传递它
public class UserOfNewBarClass {
public UserOfNewBarClass(IBar newBarClass) {
}
// Use the IBar interface
}
Run Code Online (Sandbox Code Playgroud)
此外,您可以在测试时模拟接口,这意味着您可以隔离单个具体类并完全隔离测试它们.你可以做更复杂的事情,你可以在以后学习,比如基于属性值的绑定和对你注入的内容的条件绑定.
关于入口点,请咨询这些
WCF - http://www.aaronstannard.com/post/2011/08/16/dependency-injection-ninject-wcf-service.aspx
MVC - http://www.shahnawazk.com/2010/12/dependency-injection-in-aspnet-mvc-3.html
Windows服务 - 将Ninject与Windows服务一起使用
起初很难理解,但Container(在本例中为Ninject)根据您指定的绑定计算出要注入的实现.最终目标是注入您的类所需的所有内容,以便执行它的方法,以便您可以单独测试它(它还有助于保持类清洁和整洁).首选方法是通过构造函数注入,因为类在创建时将具有所有依赖项.物业注入当然是可行的,但与属性一样,你无法保证它已被设置.