依赖注入和模拟框架之间的区别(Ninject 与 RhinoMocks 或 Moq) [英] Difference between Dependency Injection and Mocking Framework (Ninject vs RhinoMocks or Moq)

查看:25
本文介绍了依赖注入和模拟框架之间的区别(Ninject 与 RhinoMocks 或 Moq)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Ninject 与 RhinoMocks 或 Moq 等模拟框架有什么区别?我谷歌了这个,但仍然不清楚.

What is the difference between Ninject and a mocking framework like RhinoMocks or Moq? I Google'd this but it is still unclear.

推荐答案

Ninject依赖注入 .NET.

RhinoMocksMoq 都是模拟框架.

RhinoMocks and Moq are both mocking frameworks.

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

Now both have nothing to do with each other. I really had trouble understanding both so here I go trying to explain.

依赖注入:是控制反转的一种实现(让我们称之为).你不要混淆两者.您正在控制从代码中创建对象.依赖关系,比如 IRepository 不会由您的类/代码创建,而是由其他人注入,一个依赖注入框架.

Dependency Injection: is an implementation (lets call it) of Inversion of Control. You don't confuse the two. You are taking the control of creating an object out of your code. Dependencies, like say a IRepository would not be created by your classes/code but instead injected by someone else, a dependency injection framework.

假设你有

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

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

Now you have an actual implementation:

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

现在到处都是:

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

为什么?问问自己,你为什么首先要制作一个界面?因此您可以应对变化.现在,当您需要将存储库更改为其他内容时.您必须替换所有具有 new MyUserRepo() 的行.

Why? Ask yourself why you made an interface in the first place? So you can cope with change. Well now, when you need to change your repository to something else. You have to replace all the lines that have new MyUserRepo().

一个简单的方法是用户工厂方法,这是 IOC 的另一种形式.

A simple method is user a factory method which is another form of IOC.

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

并像这样使用它:

IUserRepository rep = RepoFactory.UserRepo;

现在,当您必须更改存储库时,只需更改您的工厂.依赖注入通过完成所有工作将其提升到一个新的水平.您根本不需要更改代码(或者一些声明).

Now when you have to change your repository you have to change only your factory. Dependency injection takes this to the next level by doing all the work. You don't need to change the code at all (or maybe a few declarations).

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

<小时>

模拟框架:这对我来说就像火箭科学.但史蒂文桑德森的书有一个精彩的简单解释.


A Mocking Framework : Boy this was like rocket science to me. But Steven Sandersons book had a brilliant simple explanation.

我们继续使用 IUserRepository.

现在您必须测试一些依赖于 IUserRepository 的复杂 UI/身份验证.

Now you have to test some complicated UI/Authentication whatever that depends on IUserRepository.

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

现在在您的测试中,当您使 IUserRepository 成为 MyUserRepo 的实例时.如果出现问题,您不知道出了什么问题!是您的用户控制还是您的数据库连接?

Now in your test, when you make IUserRepository an instance of MyUserRepo. If something goes wrong you don't know what went wrong! Was it your user control or your database connection?

您想让测试更具确定性,就像有人说的那样.

You want make the test more deterministic as someone said.

所以你创建了一个假的用户存储库.

So you make a fake user repository.

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

现在,当您通过这个 repo 时.如果您的测试失败了,您就知道是其他原因,而不是数据库.

So now, when you pass this fake repo. If you're test fails you KNOW it was something else, not the data base.

我的例子很简单,但如果它有大量的接口.您将需要编写大量伪造代码,大量代码膨胀!

My example was simple, but if its a large number of Interfaces. You'll need to write a lot of fake code, its a lot of code bloat!

因此您可以使用模拟框架在此处编写更少的代码.

So you can use a mocking framework to write less code here.

Moq 使用流畅的界面,非常好.使用 Moq 看起来像这样:

Moq uses a fluent interface and is quite nice. Using Moq would look like this:

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

创建假对象变得容易多了 =)

Creating fake objects becomes a lot easier =)

现在我希望您了解如何利用两者来发挥自己的优势.您可以使用模拟框架创建假对象,然后使用依赖注入在正确的时间连接正确的对象.

Now I hope your seeing how you can use both to your advantage. You can create your fake objects with a mocking framework, then use dependency injection to hook up the right objects at the right time.

对于我较小的 Silverlight 应用程序,我使用 MEF(内置于 .Net4)进行依赖注入.然后我几乎没有 #Ifdef 关于哪些类要基于 #define 符号Export(或公开)的声明.因此,我只需更改一个 #define,然后我就可以将我的应用切换为到处使用假类.

For my smaller Silverlight applications I use MEF (Inbuilt in .Net4) for Dependency Injection. And then I have little #Ifdef on the declarations for which classes to Export (or expose) Based on a #define symbol. So I just change one #define and I can switch my app to using fake classes here and there.

真的希望有帮助.

这篇关于依赖注入和模拟框架之间的区别(Ninject 与 RhinoMocks 或 Moq)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆