标签:lap 为我 扩展 send html ati 点击 size 工具
我们首先要创建的是一个空的Visual Studio solution。在这个 solution 中,我们将创建3个工程。
1. 一个域模块工程。
2.一个MVC4应用。
3.一个单元测试工程。
? ? ? ?
现在我们就创建一个名为 SportsStore 的空 solution ,
工程名 | VS工程模板 | 目的 |
SportsStore.Domain | Class Library | 使用Entity Framework?创建一个repository,并将其设置为一个持久层。 |
SportsStore.WebUI | ASP.NET MVC Web Application | controllers and views |
SportsStore.UnitTests | Unit Test Project | unit tests |
? ? ? ?
? ? ? ?
? ? ? ?
Install-Package Ninject -version 3.0.1.10
Install-Package Ninject.Web.Common -version 3.0.0.7
Install-Package Ninject.MVC3 -Version 3.0.0.6
Install-Package Moq -version 4.1.1309.1617
Install-Package Microsoft.Aspnet.Mvc -version 5.0.0
? ? ? ?
? ? ? ?
到这一步我们的项目框架的雏形已经出来了,现在我们要为它添加引用。在solusion管理器中,一次右击
每个工程,选择Add Reference。
? ? ? ?
工程名 | 工具依赖 | 工程依赖 | 微软引用 |
SportsStore.Domain | Entity Framework | None | System.Web.Mvc System.ComponentModel.DataAnnotations |
SportsStore.WebUI | Ninject Moq | SportsStore.Domain ???? | None |
SportsStore.UnitTests | Ninject Moq | SportsStore.Domain SportsStore.WebUI | System.Web.Mvc System.Web Microsoft.CSharp |
? ? ? ?
注意: System.Web.Mvc 的版本一定选择4.0.0
? ? ? ?
? ? ? ?
在我们这个应用中,对MVC框架做了很多扩展,这也是我们学习的重点内容,掌握了这些知识点,
我们再以后的开发项目中,就能得心应手,构建出稳定的,易于扩展和维护的企业应用架构。
右击 SportsStore.WebUI 工程的 Infrastructure 文件夹,选择添加类,类名为 NinjectControllerFactory ,
? ? ? ?
using?System;?? using?System.Collections.Generic;?? using?System.Linq;?? using?System.Web;?? using?System.Web.Mvc;?? using?System.Web.Routing;?? ?? ? ? ? namespace?SportStore.WebUI.Infrastructure?? {?? ???///?<summary>?? ????///?工厂类?? ???///?</summary>?? ????public?class?NinjectControllerFactory?:?DefaultControllerFactory?? ????{?? ????????private?IKernel?ninjectKernel;?? ?? ? ? ? ????????public?NinjectControllerFactory()?? ????????{?? ????????????ninjectKernel?=?new?StandardKernel();?? ????????????AddBindings();?? ????????}?? ?? ? ? ? ????????protected?override?IController?GetControllerInstance(RequestContext?? ????????????requestContext,?Type?controllerType)?? ????????{?? ????????????return?controllerType?==?null???null?:?(IController)ninjectKernel.Get(controllerType);?? ????????}?? ?? ? ? ? ????????private?void?AddBindings()?? ????????{?? ????????????//put?bindings?here?? ????????}?? ????}?? }?? |
我们现在还没有添加任何绑定,但是,当我们需要时,能使用 AddBindings 方法去添加. 现在,我们需要去
告诉 MVC 我们打算使用 NinjectController 类去创建Controller对象,要实现这一点,请打开SportsStore.WebUI工程的 Global.asax.cs?文件
? ? ? ?
public?class?Global?:?System.Web.HttpApplication?? {?? ?? ? ? ? ????protected?void?Application_Start(object?sender,?EventArgs?e)?? ????{?? ????????AreaRegistration.RegisterAllAreas();?? ????????RouteConfig.RegisterRoutes(RouteTable.Routes);?? ?? ? ? ? ????????//我们需要告诉我们想要使用?Ninject?Controller?MVC?? ????????//类来创建控制器对象?? ????????ControllerBuilder.Current.SetControllerFactory(new?? ????????????????????NinjectControllerFactory());?? ????}?? }?? |
? ? ? ?
现在我们将要启动域模块,在MVC应用中应用领域模型,能使每一件事情都变得完美,因此,域 也就必然 是启动应用的最完美的地方。因为我们要做的电子商务应用,所以,我们需要一个产品,这是在明显不过的事了。右击我们刚刚建立的 Entities 文件夹,然后新建一个C#类,命名为 Product?
namespace?SportStore.Domain.Entities?? {?? ????public?class?Product?? ????{?? ????????public?int?ProductID?{?get;?set;?}?? ????????public?string?Name?{?get;?set;?}?? ????????public?string?Description?{?get;?set;?}?? ????????public?decimal?Price?{?get;?set;?}?? ????????public?string?Category?{?get;?set;?}?? ????}?? }?? |
? ? ? ?
? ? ? ?
我们知道,我们需要一些途径或方式,去数据库中取得Product entities。为了保持架构上的完美,我们要遵循持久逻辑与域模型实体分离的原则,要做到这一点,我们使用repository 设计模式. 我们不需要担心怎样去实现持久层,我们从定义一个接口开始,去启动它。
? ? ? ?
在 Abstract 文件夹上右击,选择添加一个接口,命名为 IProductsRepository ,
namespace?SportStore.Domain.Abstract?? {?? ????public?interface?IProductRepository?? ????{?? ????????IEnumerable<Product>?Products?{?get;?}?? ????}?? }?? |
? ? ? ?
这个接口使用了 IEnumerable<T> 接口去获取一个Product对象,我们没有告诉它去哪或怎么样去取得数据,一个使用 IProductsRepository 接口的类能够取得Product 对象,而不需要知道它们从哪来或被谁传递,这就是 repository设计模式的本质。接下来我们就通过添加一些特性到我们代码中,去再次拜访一下这个接口。
? ? ?
构建一个Mock Repository
现在我们已经定义了一个 abstract interface, 我们能够实现这个持久化机制并且挂接到数据库,不过这是不是现在要做的,为了能够启动这个项目的其他部分,现在我们要创建一个 IProductsRepository 接口的 Mock 实现,我们需要在我们的 SportsStore.WebUI 工程的 NinjectControllerFactory 类的 AddBindings 方法中去做这件事。
? ? ? ?
using?System;?? using?System.Collections.Generic;?? using?System.Linq;?? using?System.Web;?? using?System.Web.Mvc;?? using?System.Web.Routing;?? using?Moq;?? using?Ninject;?? using?SportStore.Domain.Abstract;?? using?SportStore.Domain.Entities;?? ?? ? ? ? namespace?SportStore.WebUI.Infrastructure?? {?? ???///?<summary>?? ????///?工厂类?? ???///?</summary>?? ????public?class?NinjectControllerFactory?:?DefaultControllerFactory?? ????{?? ????????private?IKernel?ninjectKernel;?? ?? ? ? ? ????????public?NinjectControllerFactory()?? ????????{?? ????????????ninjectKernel?=?new?StandardKernel();?? ????????????AddBindings();?? ????????}?? ?? ? ? ? ????????protected?override?IController?GetControllerInstance(RequestContext?? ????????????requestContext,?Type?controllerType)?? ????????{?? ?? ? ? ? ????????????return?controllerType?==?null???null?:?(IController)ninjectKernel.Get(controllerType);?? ????????}?? ?? ? ? ? ????????private?void?AddBindings()?? ????????{?? ????????????//告诉Moq想使用哪种模仿对象?? ????????????Mock<IProductRepository>?mock?=?new?Mock<IProductRepository>();?? ????????????//Setup?给模仿对象添加一个方法?? ????????????//Returns?调用模仿方法时?Moq?返回的结果?? ????????????mock.Setup(m?=>?m.Products).Returns(new?List<Product>?{?? ????????????????new?Product?{?Name?=?"Football",?Price?=?25?},?? ????????????????new?Product?{?Name?=?"Surf?board",?Price?=?179?},?? ????????????????new?Product?{?Name?=?"Running?shoes",?Price?=?95?}?? ????????????????});?? ????????????//ToConstant?表示,应该将服务绑定到指定的常数值。?? ????????????ninjectKernel.Bind<IProductRepository>().ToConstant(mock.Object);?? ????????????//put?bindings?here?? ????????}?? ????}?? }?? |
? ? ? ?
无论?IProductsRepository 在哪获得了一个请求,?我们都需要 Ninject 去返回同样的 mock 对象,这就是 为什么我们使用 ToConstant 方法的原因。
...
ninjectKernel.Bind<IProductRepository>().ToConstant(mock.Object);
? ? ? ?
? ? ? ?
已经做了这么久,我们还没有看到任何可视化的效果,这对于有些心急的朋友来说是不公平的,看不见有任何成绩出来,将会打击我们做项目的信心,这对开发团队是很不利的事情,现在就让我们添加一个Controller 到 SportsStore.WebUI 工程中,选择添加控制器,命名为 ProductController,确保模板选型为空,如下图:
? ? ? ?
? ? ? ?
接下来,你要删除VS自动为你添加的代码,并用如下代码代替:
using?System;?? using?System.Collections.Generic;?? using?System.Linq;?? using?System.Web;?? using?System.Web.Mvc;?? using?SportStore.Domain.Abstract;?? ?? ? ? ? namespace?SportStore.WebUI.Controllers?? {?? ????public?class?ProductController?:?Controller?? ????{?? ????????private?IProductRepository?repository;?? ????????public?ProductController(IProductRepository?productRepository)?? ????????{?? ????????????this.repository?=?productRepository;?? ????????}?? ?? ? ? ? ????????public?ViewResult?List()?? ????????{?? ????????????return?View(repository.Products);?? ????????}?? ????}?? }?? |
? ? ? ?
现在要做的是添加一个View,在 List 方法上右击并选择添加View,如图:
? ? ? ?
这里请注意了,在模型类的下拉列表中,你并不能找到 IEnumerable<SportsStore.Domain.Entities.Product> 项,你需要手工输入它。然后,点击添加按钮,创建View。
? ? ? ?
渲染View数据
@model?IEnumerable<SportsStore.Domain.Entities.Product>?? ??? ? ? ? @{?? ????ViewBag.Title?=?"Products";?? }?? @foreach?(var?p?in?Model)?{?? <div?class="item">?? ????????<h3>@p.Name</h3>?? ????????@p.Description?? ????????<h4>@p.Price.ToString("c")</h4>?? </div>?? }?? |
? ? ? ?
我们改变一下这个页的标题,注意这里我们不需要使用 Razor text 或者 @:elements 去展示数据,因为每行内容都是一个 HTML 元素.
? ? ? ?
? ? ? ?
现在我们需要去做的,就是告诉MVC框架,当一个请求到达时,我们的网站要映射到ProductController类的List 活动方法,这需要去修改App_Start/RouteConfig.cs 文件的 RegisterRoutes 方法,
? ? ? ?
routes.MapRoute(?? ????????????????name:?"Default",?? ????????????????url:?"{controller}/{action}/{id}",?? ????????????????defaults:?new?{?controller?=?"Product",?action?=?"List",?id?=?UrlParameter.Optional?}?? ????????????);?? |
? ? ? ?
完成修改后,运行你的应用,你将看到如下画面:
???? |
? ? ??
《精通ASP.NET MVC5》第7章 SportStore:一个真正的应用程序(1)
标签:lap 为我 扩展 send html ati 点击 size 工具
原文地址:http://www.cnblogs.com/tangge/p/6351221.html