2013-02-12 83 views
3

我已阅读或试图阅读太多“如何”,并且已经完全无处可去。统一? System.Web.Http.Dependencies? Ninject? StructureMap?啊。我只想要简单的工作!我无法弄清楚这是什么现状。有非常不同的方法,这些例子似乎不完整。哎呀,最好的领导有一个样本项目...我无法加载VS2010或2012. ARG!我每天3/4的时候都会觉得应该有半个小时的时间,然后继续前进!这只是水暖!如何为MVC4/VS2012/Web API注入控制器

我有一个基于泛型的存储库来处理大量支持相同操作的数据集。

IRepository

我想控制其库中的每个数据集被绑定到。这将允许我将所有内容绑定到测试XML存储库,随着项目的进展将它们转换到SQL存储库。

我当然希望得到一些帮助得到这个去!谢谢!

+0

我只是删除一切,并试图再次统一,因为这是我来最接近的一次。在预感上,我删除了一个构造函数,它带有参数,我认为它工作。我不知道为什么当空的构造函数可用时它锁定在构造函数上(我所做的只是评论其他)。明天早上将继续关注此事。 – 2013-02-12 21:48:29

回答

3

听起来像你是在我几年前的状态。

请注意,如果您需要更多帮助,我会向您发送一些代码。很难把所有的代码放在这里。

我试着解释我正在开发的项目中的当前体系结构。这篇文章有点冗长,但我想给你一个关于如何使用IOC在很多方面可以帮助你的大局。

所以我使用Ninject。在尝试使用Castle Windsor一段时间后,我发现Ninject易于启动和运行。 Ninject有一个很酷的网站,可以帮助你入门。

我所有的项目结构首先如下:(自上而下和它的MVC)

查看 - 剃刀 视图模型 - 我用按次1个视图模型

ViewModelBuilder - 为我的视图构建我的视图模型(用于将代码从我的控制器中抽离出来,以便控制器保持整洁)

AutoMapper - 域实体映射到我的视图模型

控制器 - 叫我的服务层来获得域实体

域实体 - 我的域名

ServiceLayer(业务交涉层) - 调用我的存储库层以获取域实体或这些的集合

AutoMapper再次 - 从我的第三方供应商映射自定义类型转换成我的域实体

RepositoryLayer - 确实CRUD操作我的数据存储

这是一个层次,但类型的域实体沿侧坐并用于几个不同的层。

注:在这篇文章中提到的一些额外的工具有:

AutoMapper - 地图实体到其他实体 - 无需编写映射代码

起订量负载 - 允许你嘲笑单元测试的东西。这在后面会提到。

现在,关于Ninject。

每层都标有接口。必须这样做,Ninject才能对自己说。

当我发现IVehicleRepository注入一个真正的VehicleRepository,甚至注入它与FakeVehicleRepository,如果我需要一个假的。

(这涉及到你的评论 - “这将让我的一切绑定到一个测试XML库”)

现在,每一层都有contstructor使Ninject(或任何其它的IOC容器)可以注入需要的东西:

public VehicleManager(IVehicleRepository vehicleRepository) 
{ 
    this._vehicleRepository = vehicleRepository; 
} 

VehicleManager位于我的serviceLayer中(不要与任何与Web服务相关的混淆)。服务层实际上就是我们所说的业务层。似乎很多人都在使用文字服务。 (尽管我认为这很烦人,因为它让我想到Web服务或WCF,而不仅仅是一个业务层......无论如何......)

现在没有进入Ninject的基本设置下面的行在我的NinjectWebCommon.cs代码告诉ninject做什么:

kernel.Bind<IVehicleRepository>().To<VehicleRepository>().InRequestScope(); 

这是说:

嘿ninject,当我问IVehicleRepository给我一个具体的实施VehicleRepository的。

如前所述,我可以将VehicleRepository替换为FakeVehicleRepository,这样我就不必从真实数据库中读取数据。

因此,正如你现在可以想象的那样,每一层只依赖于接口。

我不知道你做了多少单元测试,但你也可以想象,如果你想单元测试你的服务层,并且它具有对你的存储库层的具体引用,那么你将无法像你一样进行单元测试实际上打你的存储库,因此从一个真正的数据库中读取。

记住单元测试称为单元测试,因为它只测试一件事情。因此单词UNIT。所以,因为每个人都只知道接口,这意味着你可以在你的服务层上测试一个方法并模拟库。

所以,如果你的服务层具有这样的方法:

public bool ThisIsACar(int id) 
{ 
    bool isCar = false; 
    var vehicle = vehicleRepository.GetVehicleById(id); 

    if(vehicle.Type == VehicleType.Car) 
    { 
     isCar = true; 
    } 
    else 
    { 
     isCar = false; 
    } 
} 

你不会希望vehicleRepository要打电话,所以你可以起订量是什么VehicleRepository给你。如果它实现了一个接口,你大多只能使用Mock的东西。

So your unit test would look like this (some pseudo code here): 
     [TestMethod] 
     public void ServiceMethodThisIsACar_Returns_True_When_VehicleIsACar() 
     { 
      // Arrange 
      _mockRepository.Setup(x => x.ThisIsACar(It.IsAny<int>)).returns(new Car with a type of VehicleType.Car) 

      // Act 
      var vehicleManager = new VehicleManager(_mockVehicleRepository.Object); 
      var vehicle = vehicleManager.ThisIsACar(3); 

      // Assert 
      Assert.IsTrue(vehicle.VehicleType == VehicleType.Car) 
     } 

因此,大家可以看到,在这一点上,这是非常简单的,你只想要测试的IF语句在服务层,以确保结果是正确的。

你会在自己的单元测试中测试你的仓库,如果你正在使用它,可能会模拟实体框架的工作。

所以,总的来说,我会说,使用任何IOC容器都能让你以最少的痛苦快速运行。

我也会说,尝试和单元测试一切,你可以。这有很多不同的原因。很明显,它会测试你编写的代码,但它也会立即告诉你,如果你做了一些愚蠢的事情,比如新建一个具体的存储库。你会很快看到你不会有一个接口来模拟你的单元测试,这将导致你回去重构你的代码。

我发现使用IOC,需要一段时间才能得到它。它把你的垃圾混淆直到有一天它只是点击。在那之后,你很容易想到你如何在没有它的情况下生活。

这里的东西我不能生活在没有 Automapper 起订量 流利验证 ReSharper的清单 - 有些恨它,我喜欢它,主要是它的单元测试UI。

无论如何,这是太长了。让我知道你的想法。

感谢 拉斯

+0

谢谢拉斯。直到今天我才看到这种反应。我认为没有人回复,因为我从来没有收到通知。不知道为什么。我选择了3个小时。顺便说一句 - 自动映射器不再适用于SL,就像V5一样。我不得不切换到OMU。 – 2013-02-21 19:34:26

+0

嗨托德。你是什​​么意思你选了3个小时?你可以重新写你的评论,因为我不明白一半吗?您可能需要添加新评论。对不起。 – RuSs 2013-02-22 00:17:06