asp.net-web-api - 如何为MVC4/VS2012/Web API注入(inject) Controller

标签 asp.net-web-api dependencies code-injection

我已经阅读或尝试阅读过多的“操作方法”,却一无所获。统一? System.Web.Http.Dependencies? Ninject? StructureMap?啊。我只想要一些简单的可行的方法!我只是不知道它的当前状态是什么。有很多不同的方法,示例似乎并不完整。最好的线索有一个示例项目,我无法在VS2010或2012中加载。我浪费了一天3/4的时间,我觉得本该最多应该花半个小时才能继续前进!只是水暖!

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

知识库

我想控制每个数据集绑定(bind)到哪个存储库。这将使我可以将所有内容绑定(bind)到测试XML存储库,并随着项目的进行将它们过渡到SQL存储库。

我一定会很乐意为您提供帮助!谢谢!

最佳答案

听起来像您是几年前的状态。

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

我将尝试解释我正在研究的项目中的当前体系结构。这篇文章有些冗长,但我想向您全面介绍如何使用IOC可以在许多方面为您提供帮助。

所以我用Ninject。尝试使用温莎城堡一段时间后,我发现Ninject易于安装和运行。 Ninject有一个不错的网站,它将帮助您入门。

首先,我的项目结构如下:(自上而下,它是MVC)

查看-剃刀
ViewModel -我为每个 View 使用1个 View 模型

ViewModelBuilder -为我的 View 构建我的 View 模型(用于将代码抽象到我的 Controller 之外,以便我的 Controller 保持整洁)

AutoMapper -将域实体映射到我的 View 模型

Controller -调用我的服务层以获取域实体

域实体-我的域的表示形式

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

AutoMapper再次-将来自第三方供应商的自定义类型映射到我的域实体中

RepositoryLayer -对我的数据存储区执行CRUD操作

这是一个层次结构,但Domain实体位于旁边,并在几个不同的层中使用。

注意:本文中提到的一些额外工具是:

AutoMapper -将实体映射到其他实体-无需编写大量映射代码

Moq -允许您模拟东西进行单元测试。稍后会提到。

现在,关于Ninject。

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

当我找到IVehicleRepository时,将其注入真实的VehicleRepository,或者如果我需要假的,甚至将其注入FakeVehicleRepository。

(这与您的评论有关-“这将使我可以将所有内容绑定(bind)到测试XML存储库”)

现在,每个层都有一个构造函数,因此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实现。

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

因此,正如您现在可以想象的那样,每一层仅依赖于接口(interface)。

我不知道您已经进行了多少单元测试,但是您也可以想象,如果您想对服务层进行单元测试,并且它对存储层有具体的引用,那么您将无法进行单元测试,因为您实际上会遇到问题。存储库,并因此从真实数据库中读取。

请记住,单元测试称为单元测试,因为它仅测试一项。因此,单词UNIT。因此,因为一切都只知道接口(interface),所以这意味着您可以在服务层上测试方法并模拟存储库。

因此,如果您的服务层具有如下方法:
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退还给您的内容。如果实现了接口(interface),则大多数情况下只能模拟它们。
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容器来使您起步并以最少的痛苦运行得最快。

我还要说,尽力对单元进行测试。出于几个不同的原因,这很不错。显然,它可以测试您编写的代码,但是如果您做过一些愚蠢的事情(例如新建一个具体的存储库),它也会立即向您显示。您很快就会发现,在单元测试中没有模拟接口(interface),这将使您返回并重构代码。

我发现使用IOC会花一些时间。直到有一天它单击时,它会使您感到困惑。之后,它是如此的容易,您想知道没有它的生活。

这是我不能没有的生活清单
自动映射器
起订量
流利验证
Resharper-我非常讨厌它,主要是因为其单元测试UI。

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

谢谢
俄罗斯

关于asp.net-web-api - 如何为MVC4/VS2012/Web API注入(inject) Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14842061/

相关文章:

java - 未找到代理 JAR 或没有代理类属性

javascript - 在维护 HTML 的同时避免 JavaScript 注入(inject)?

javascript - 使 Javascript 代码黑客攻击/注入(inject)/操纵变得困难的方法?

c# - jQuery ajax 发布当前日期时间 ASP.NET Web API

jquery - 在 WebAPI 中进行 POST 调用时,请求的资源不支持 http 方法 'GET"

在 Makefile 中处理链接的正确方法?

ruby-on-rails - 对 Rails 初始值设定项中的 fixture 数据的依赖

即使我可以看到返回的 JSON 有效负载,对跨域的 jQuery ajax 调用也会返回状态 404

asp.net-web-api - Swagger 2.0 未显示响应类架构

java - Ivy 依赖配置映射通配符