dependency injection和Mocking框架之间的区别(Ninject vs RhinoMock或Moq)

那么Ninject和RhinoMock或moq之类的模拟框架有什么区别呢? 我谷歌,但它仍然不清楚。

Ninject是.NET的dependency injection 。

RhinoMocks和Moq都是嘲讽的框架。

现在两者都没有任何关系。 我真的很难理解,所以我在这里试着解释一下。

dependency injection :是Inversion of Control的一个实现(我们称之为)。 你不要混淆两者。 你正在控制从你的代码中创build一个对象。 依赖关系,比如说一个IRepository不会由你的类/代码创build,而是由其他人注入一个dependency injection框架。

可以说你有

 interface IUserRepository { string GetUserName(int id);//one method for simplicity } 

现在你有一个实际的实现:

 class MyUserRepo : IUserRepository { string GetUserName(int id) { //grab your username from your data base here. } } 

现在到处都是,你会有:

 IUserRepository repo = new MyUserRepo();//this is bad!! 

为什么? 问问你自己为什么首先做了一个界面? 所以你可以应付变化 。 那么现在,当你需要改变你的存储库到别的东西。 您必须replace所有具有new MyUserRepo()

一个简单的方法是用户工厂方法,这是IOC的另一种forms。

 class RepoFactory { public static IUserRepository UserRepo { get {return MyUserRepo();} } } 

像这样使用它:

 IUserRepository rep = RepoFactory.UserRepo; 

现在,当你不得不改变你的仓库时,你只能改变你的工厂。 通过完成所有的工作, dependency injection将它带到下一个层次。 你根本不需要改变代码(或者可能是一些声明)。

 IUserRepository repo; //this magically gets the right instance based on some config somewhere. 

一个嘲弄的框架 :男孩,这对我来说就像火箭科学。 但史蒂文桑德森的书有一个辉煌的简单的解释。

我们继续与IUserRepository

现在你必须testing一些复杂的UI /authentication,不pipe依赖于IUserRepository

 class UserDisplay : UserControl { UserDisplay(IUserRepository repo) {//display the username or something here.. } } 

现在在你的testing中,当你使IUserRepository成为IUserRepository一个实例。 如果出现问题,你不知道出了什么问题! 是你的用户控件还是你的数据库连接?

你想让testing更确定,正如有人所说。

所以你做了一个假的用户存储库。

 class FakeUserRepo : IUserRepository { public string GetUserName(int id) { return "FakeUser"; } } 

所以,现在,当你通过这个回购。 如果你testing失败,你知道这是另一回事,而不是数据库。

我的例子很简单,但如果它有大量的接口。 你需要写很多的代码,它的代码膨胀了很多!

所以你可以使用一个模拟框架在这里写更less的代码。

Moq使用stream畅的界面,相当不错。 使用Moq将如下所示:

 var fakeUserRepo = new Mock<IUserRepository>(); fakeUserRepo.Setup(f => f.GetUserName(It.IsAny<int>)).Returns("FakeUser"); //does the same thing as the class declaration fakeUserRepo.Object;//this returns fake object of type IUserRepository 

创build假对象变得更容易=)

现在,我希望你看到你如何使用你的优势。 你可以用一个模拟框架来创build你的假对象,然后使用dependency injection来在正确的时间连接正确的对象。

对于我的小型Silverlight应用程序,我使用MEF (内置在.Net4中)进行dependency injection。 然后,我有一些#Ifdef的基于#define符号Export (或公开)类的声明。 所以我只是改变一个#define ,我可以切换我的应用程序在这里和那里使用假类。

真的希望有帮助。

Ninject是控制工具的dependency injection/反转。 你用它来pipe理类之间的依赖关系。

经典的例子是如果你有一个像服务或数据存储库的东西。 不要在整个应用程序中使用具体类,而是要求Ninject内核为您提供一个接口的实例。 这意味着你可以创build多个实现接口的具体类,并在一个地方交换出来。 这在testing中非常有用,但远远超出了这个范围。 很多IoC容器,Ninject也不例外,也会做一些事情,比如pipe理实例生命周期和其他一些东西。 如果你想要每个Web请求使用一个存储库,或者一个类的单个实例,那么Ninject可以很干净地为你处理这种事情。

Moq,RhinoMocks等都是嘲讽的框架,它们会产生假类,让你断言应用程序的其他部分以正确的方式与它们交互。 这些只对testing有用,因为模拟对象除了报告访问方式之外,不提供任何function。

你也许还想看看StructureMap – structuremap.net/structuremap – 他们有一些很好的文章来描述这个模式,Rob Conery也在IoC上做了一些插曲 – http://www.asp.net/mvc/videos/aspnet-mvc -storefront-part-13-dependency-injection – and on Mocking – http://www.asp.net/mvc/videos/aspnet-mvc-storefront-part-12-mocking – 这是一个很好的手表,描述更好比我能做的每件事都要多。