依赖注入和模拟框架之间的区别(Ninject vs RhinoMocks 或 Moq)

2024-03-08

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


Ninject http://ninject.org/ is 依赖注入 http://en.wikipedia.org/wiki/Dependency_injection对于.NET。

犀牛模型 http://www.ayende.com/projects/rhino-mocks.aspx and Moq http://code.google.com/p/moq/都是模拟框架。

现在两人已经没有任何关系了。我真的很难理解两者,所以我在这里尝试解释一下。

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

假设你有

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!!

为什么?问问自己为什么要创建界面?所以你可以应对change。现在,当您需要将存储库更改为其他内容时。您必须替换所有具有的行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";
   }
}

所以现在,当你通过这个fake回购。如果您的测试失败,您知道这是其他原因,而不是数据库。

我的例子很简单,但是如果它有大量的接口。你需要写很多fake代码,代码很多,臃肿!

所以你可以使用模拟框架在这里编写更少的代码。

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 http://mef.codeplex.com/(内置于.Net4)用于依赖注入。然后我就很少了#Ifdef关于哪些类的声明Export(或暴露)基于#define象征。所以我只换一个#define我可以将我的应用程序切换为到处使用假类。

真的希望这有帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

依赖注入和模拟框架之间的区别(Ninject vs RhinoMocks 或 Moq) 的相关文章

  • 在 Xamarin Android 中将图像从 URL 异步加载到 ImageView 中

    我有一个包含多个项目的 ListView 列表中的每个项目都应该有一个与之关联的图像 我创建了一个数组适配器来保存每个列表项并具有我希望加载的图像的 url 我正在尝试使用 Web 请求异步加载图像 并设置图像并在加载后在视图中更新它 但视
  • C++ 求二维数组每一行的最大值

    我已经设法用这个找到我的二维数组的每一行的最小值 void findLowest int A Cm int n int m int min A 0 0 for int i 0 i lt n i for int j 0 j lt m j if
  • SSH 主机密钥指纹与模式 C# WinSCP 不匹配

    我尝试通过 WinSCP 使用 C 连接到 FTPS 服务器 但收到此错误 SSH 主机密钥指纹 与模式不匹配 经过大量研究 我相信这与密钥的长度有关 当使用 服务器和协议信息 下的界面进行连接时 我从 WinSCP 获得的密钥是xx xx
  • C# 中值类型和引用类型有什么区别? [复制]

    这个问题在这里已经有答案了 我知道一些差异 值类型存储在堆栈上 而引用类型存储在托管堆上 值类型变量直接包含它们的值 而引用变量仅包含对托管堆上创建的对象位置的引用 我错过了任何其他区别吗 如果是的话 它们是什么 请阅读 堆栈是一个实现细节
  • C# 中可空类型是什么?

    当我们必须使用nullable输入 C net 任何人都可以举例说明 可空类型 何时使用可空类型 https web archive org web http broadcast oreilly com 2010 11 understand
  • 如何针对 Nancy 中的 Active Directory 进行身份验证?

    这是一篇过时的文章 但是http msdn microsoft com en us library ff650308 aspx paght000026 step3 http msdn microsoft com en us library
  • C# 用数组封送结构体

    假设我有一个类似于 public struct MyStruct public float a 我想用一些自定义数组大小实例化一个这样的结构 在本例中假设为 2 然后我将其封送到字节数组中 MyStruct s new MyStruct s
  • c# Asp.NET MVC 使用FileStreamResult下载excel文件

    我需要构建一个方法 它将接收模型 从中构建excel 构建和接收部分完成没有问题 然后使用内存流导出 让用户下载它 不将其保存在服务器上 我是 ASP NET 和 MVC 的新手 所以我找到了指南并将其构建为教程项目 public File
  • HttpClient 像浏览器一样请求

    当我通过 HttpClient 类调用网站 www livescore com 时 我总是收到错误 500 可能服务器阻止了来自 HttpClient 的请求 1 还有其他方法可以从网页获取html吗 2 如何设置标题来获取html内容 当
  • 使用安全函数在 C 中将字符串添加到字符串

    我想将文件名复制到字符串并附加 cpt 但我无法使用安全函数 strcat s 来做到这一点 错误 字符串不是空终止的 我确实设置了 0 如何使用安全函数修复此问题 size strlen locatie size nieuw char m
  • 我的 strlcpy 版本

    海湾合作委员会 4 4 4 c89 我的程序做了很多字符串处理 我不想使用 strncpy 因为它不会终止 我不能使用 strlcpy 因为它不可移植 只是几个问题 我怎样才能让我的函数正常运行 以确保它完全安全稳定 单元测试 这对于生产来
  • 初始化变量的不同方式

    在 C 中初始化变量有多种方法 int z 3 与 int 相同z 3 Is int z z 3 same as int z z 3 您可以使用 int z z 3 Or just int z 3 Or int z 3 Or int z i
  • C 中的位移位

    如果与有符号整数对应的位模式右移 则 1 vacant bit will be filled by the sign bit 2 vacant bit will be filled by 0 3 The outcome is impleme
  • 在 URL 中发送之前对特殊字符进行百分比编码

    我需要传递特殊字符 如 等 Facebook Twitter 和此类社交网站的 URL 为此 我将这些字符替换为 URL 转义码 return valToEncode Replace 21 Replace 23 Replace 24 Rep
  • 已过时 - OpenCV 的错误模式

    我正在使用 OpenCV 1 进行一些图像处理 并且对 cvSetErrMode 函数 它是 CxCore 的一部分 感到困惑 OpenCV 具有三种错误模式 叶 调用错误处理程序后 程序终止 Parent 程序没有终止 但错误处理程序被调
  • ListDictionary 类是否有通用替代方案?

    我正在查看一些示例代码 其中他们使用了ListDictionary对象来存储少量数据 大约 5 10 个对象左右 但这个数字可能会随着时间的推移而改变 我使用此类的唯一问题是 与我所做的其他所有事情不同 它不是通用的 这意味着 如果我在这里
  • 在Linux中使用C/C++获取机器序列号和CPU ID

    在Linux系统中如何获取机器序列号和CPU ID 示例代码受到高度赞赏 Here http lxr linux no linux v2 6 39 arch x86 include asm processor h L173Linux 内核似
  • 将变量分配给另一个变量,并将一个变量的更改反映到另一个变量中

    是否可以将一个变量分配给另一个变量 并且当您更改第二个变量时 更改会瀑布式下降到第一个变量 像这样 int a 0 int b a b 1 现在 b 和 a 都 1 我问这个问题的原因是因为我有 4 个要跟踪的对象 并且我使用名为 curr
  • C++ 成员函数中的“if (!this)”有多糟糕?

    如果我遇到旧代码if this return 在应用程序中 这种风险有多严重 它是一个危险的定时炸弹 需要立即在应用程序范围内进行搜索和销毁工作 还是更像是一种可以悄悄留在原处的代码气味 我不打算writing当然 执行此操作的代码 相反
  • 如何连接字符串和常量字符?

    我需要将 hello world 放入c中 我怎样才能做到这一点 string a hello const char b world const char C string a hello const char b world a b co

随机推荐