那么Ninject&和Ninject之间的区别是什么?像RhinoMock或moq这样的模拟框架?我谷歌这个,但目前还不清楚。
答案 0 :(得分:97)
RhinoMocks和Moq都是嘲弄框架。
现在两者都没有任何关系。我真的很难理解两者,所以在这里我试着解释一下。
依赖注入:是Inversion of Control的一个实现(让我们称之为)。你不要混淆两者。您正在控制从代码中创建对象。依赖性,比如说IRepository
不会由您的类/代码创建,而是由其他人注入,依赖注入框架。
让我们说你有
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!!
为什么呢?问问自己为什么你首先创建了一个界面?因此,您可以应对更改。那么现在,当您需要将存储库更改为其他内容时。您必须替换new MyUserRepo()
。
一个简单的方法是用户工厂方法,它是IOC的另一种形式。
class RepoFactory
{
public static IUserRepository UserRepo
{
get {return MyUserRepo();}
}
}
并像这样使用它:
IUserRepository rep = RepoFactory.UserRepo;
现在,当您必须更改存储库时,您只需更改工厂。 依赖注入通过完成所有工作将其提升到新的水平。您根本不需要更改代码(或者可能是一些声明)。
IUserRepository repo;
//this magically gets the right instance based on some config somewhere.
模拟框架:男孩这对我来说就像火箭科学一样。但史蒂芬桑德森的书中有一个很简单的解释。
我们继续IUserRepository
。
现在你必须测试一些复杂的UI /身份验证,这取决于IUserRepository
。
class UserDisplay : UserControl
{
UserDisplay(IUserRepository repo)
{//display the username or something here..
}
}
现在,在您的测试中,当IUserRepository
成为MyUserRepo
的实例时。如果出现问题你不知道出了什么问题!它是您的用户控件还是您的数据库连接?
你想让测试更具确定性,就像有人说的那样。
所以你制作一个虚假的用户存储库。
class FakeUserRepo : IUserRepository
{
public string GetUserName(int id)
{
return "FakeUser";
}
}
所以现在,当你通过这个假的回购时。如果你测试失败,你知道它是别的东西,而不是数据库。
我的例子很简单,但是如果它有大量的接口。你需要写很多假的代码,它的代码很多!
因此,您可以使用模拟框架在此处编写更少的代码。
Moq使用流畅的界面,非常好。使用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
创建假对象变得容易多了=)
现在我希望你能看到如何利用这两种优势。您可以使用模拟框架创建虚假对象,然后使用依赖注入在正确的时间连接正确的对象。
对于我较小的Silverlight应用程序,我使用MEF(内置于.Net4)进行依赖注入。然后我对#Ifdef
(或暴露)类的声明的Export
很少基于#define
符号。所以我只需更改一个#define
,然后我就可以将我的应用切换到在这里和那里使用假类。
真的希望这很有帮助。
答案 1 :(得分:4)
Ninject是控制工具的依赖注入/反转。您可以使用它来管理类之间的依赖关系。
经典的例子是你有类似服务或数据存储库的东西。您可以要求Ninject内核为您提供接口实例,而不是在整个应用程序中使用具体类。这意味着您可以创建多个实现接口的具体类,并在一个地方交换它们。这在测试中非常有用,但远不止于此。很多IoC容器,Ninject也不例外,也会做一些事情,比如管理实例生命周期和其他一些东西。假如你想为每个web请求使用1个存储库,或者是一个类的单个实例,那就是Ninject可以非常干净地为你处理的事情。
Moq,RhinoMocks等是模拟框架,它们为您生成假类,以断言应用程序的其他部分以正确的方式与它们交互。这些实际上只对测试有用,因为模拟对象除了报告它们的访问方式之外不提供任何功能。
您可能还想查看StructureMap - structuremap.net/structuremap - 他们有一些描述模式的好文章,还有Rob Conery在IoC上的剧集 - http://www.asp.net/mvc/videos/aspnet-mvc-storefront-part-13-dependency-injection - 以及Mocking - {{3} - 这是一个很好的手表,并且描述的远比我能做的更好。