《精通ASP.NET MVC5》第7章 SportStore:一个真正的应用程序(1)

7.1 开始

7.1.1 解决方案

我们首先要创建的是一个空的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

? ? ?
?

? ? ?
?

? ? ?
?

7.1.2 安装工具包

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

? ? ?
?

? ? ?
?

7.1.3 项目之间的引用

到这一步我们的项目框架的雏形已经出来了,现在我们要为它添加引用。在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

? ? ?
?

7.1.4 设置DI Container

? ? ?
?

在我们这个应用中,对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());??

????}??

}??

? ? ?
?

7.2 启动域模块

现在我们将要启动域模块,在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;?}??

????}??

}??

? ? ?
?

7.2.1 创建抽象存储库

? ? ?
?

我们知道,我们需要一些途径或方式,去数据库中取得Product entities。为了保持架构上的完美,我们要遵循持久逻辑与域模型实体分离的原则,要做到这一点,我们使用repository 设计模式. 我们不需要担心怎样去实现持久层,我们从定义一个接口开始,去启动它。

? ? ?
?

在 Abstract 文件夹上右击,选择添加一个接口,命名为
IProductsRepository ,


namespace?SportStore.Domain.Abstract??

{??

????public?interface?IProductRepository??

????{??

????????IEnumerable<Product>?Products?{?get;?}??

????}??

}??

? ? ?
?

这个接口使用了 IEnumerable<T> 接口去获取一个Product对象,我们没有告诉它去哪或怎么样去取得数据,一个使用 IProductsRepository
接口的类能够取得Product 对象,而不需要知道它们从哪来或被谁传递,这就是 repository设计模式的本质。接下来我们就通过添加一些特性到我们代码中,去再次拜访一下这个接口。

? ?
?

7.2.2 创建模仿存储库

构建一个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);

? ? ?
?

7.3 显示产品列表

? ? ?
?

7.3.1 添加控制器

已经做了这么久,我们还没有看到任何可视化的效果,这对于有些心急的朋友来说是不公平的,看不见有任何成绩出来,将会打击我们做项目的信心,这对开发团队是很不利的事情,现在就让我们添加一个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);??

????????}??

????}??

}??

? ? ?
?

7.3.2 添加视图

现在要做的是添加一个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 元素.

? ? ?
?

7.3.3 设置默认路由

? ? ?
?

现在我们需要去做的,就是告诉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?}??

????????????);??

? ? ?
?

完成修改后,运行你的应用,你将看到如下画面:


????

? ? ??

时间: 2024-12-08 00:27:45

《精通ASP.NET MVC5》第7章 SportStore:一个真正的应用程序(1)的相关文章

ASP.NET + MVC5 入门完整教程八 -—-- 一个完整的应用程序(下)

https://blog.csdn.net/qq_21419015/article/details/80802931 SportsStore 1.导航 添加导航控件 如果客户能够通过产品列表进行分类导航,SportsStore 程序会更加实用.那么如何实现过滤产品列表,这里首先要从是视图类模型 ProductsListViewModel 开始,对该类进行如下修改: 添加一个新的属性 CurrentCategory ,接着更新 Product 控制器,使得 List 动作方法能够通过分类来过滤 P

第二章 做一个简短的C++程序

第二章 做一个简短的C++程序 2.  输出语句的使用 endl要调用flush函数刷新缓冲区,而\n不需要调用 4.iostream与iostream.h的区别 5.  重名问题 释放命名空间的两种方法(1.所有 2局部) using namespace std; using std::endl; 本章总结: 1 //#include<iostream.h> 2 #include<iostream> //标准输入输出流,包含于std中,包含了cin.cout等关键字 3 usin

ASP.NET MVC5 第4章

参考资料<ASP.NET MVC5 高级编程>第5版 第4章 模型 本章所探讨的模型是要显示.保存.创建.更新和删除的对象. 基架指使用 MVC 提供的工具为每个模型对象的标准索引构建.创建.编辑和删除功能构建控制器和视图.这个构建工作称为基架(scaffolding). 4.1 建模 4.2 构造基架 新建的ASP.NET MVC5 项目会自动包含对实体类框架(EF) 的引用.EF 是一个对象关系映射(object-relational mapping)框架.它知道如何在关系型数据库中保存.

ASP.NET MVC5(一)—— URL路由

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 using System.Web.Mvc.Routing.Constraints; 7 using System.Web.Routing; 8 9 namespace UrlAndRoutes 10 { 11 public class RouteConfig 1

Asp.Net MVC5入门学习系列②

原文:Asp.Net MVC5入门学习系列② 添加一个Controller(控制器) 因为我们用的是Asp.Net MVC,MVC最终还是一套框架,所以我们还是需要遵循它才能玩下去,或者说是更好的利用来便于我们的开发,要是对MVC概念还有点模糊的,可以去我以前写的第一话 Asp.Net MVC 3.0[Hello World!]里开始部分就对此做了阐述.假定所有跟我一起学的都了解MVC的这么一个概念,我们就开始下面的步骤了: 现在我们开始添加一个Controller,具体如下: 我们选择创建一个

ASP.NET MVC5 高级编程 第3章 视图

参考资料<ASP.NET MVC5 高级编程>第5版 第3章 视图 3.1 视图的作用 视图的职责是向用户提供界面. 不像基于文件的框架,ASP.NET Web Forms 和PHP ,视图本身并不被访问,浏览器,并不能直接指向一个视图并渲染它.相反视图被控制器渲染,因为控制器提供了渲染所需要的数据. 一般情况下,控制器需要向视图提供一些信息,所以这会传递一个数据转移对象,叫做模型.完成这一过程需要两部分操作,其中一个是检查由控制器提交的模型对象,另一个是将其内容转化为HTML格式. 3.2

ASP.NET MVC5 高级编程 第2章 控制器

参考资料<ASP.NET MVC5 高级编程>第5版 第2章 控制器 控制器:响应用户的HTTP 请求,并将处理的信息返回给浏览器. 2.1 ASP.NET MVC 简介 MVC 模式中的控制器(controller)主要负责响应用户的输入,并且在响应时修改(Model).通过这种方式,MVC 中的Controller 主要关注的是应用程序流,输入数据的处理,以及对相关视图(View)数据来源的提供 MVC 模式中 URL 首先告诉路由去实例化哪个控制器,调用哪个方法,并为该方法提供需要的参数

ASP.NET MVC5 高级编程 第5章 表单和HTML辅助方法

参考资料<ASP.NET MVC5 高级编程>第5版 第5章 表单和HTML辅助方法 5.1 表单的使用 5.1.1 action 和 method 特性 默认情况下,表单发送的是 HTTP Post 请求 EF 对于外键关系,数据库名称等也有约定.这些约定取代了以前需要提供给一个关系对象映射框架的所有映射和配置. GET 方法:GET 请求的所有参数都在URL中,因此可以为GET 请求建立书签. POST 方法:浏览器把输入值放入 HTTP 请求的主体中. 5.2 辅助方法 可以通过视图的H

学习ASP .NET MVC5官方教程总结(七)Edit方法和Edit视图详解

学习ASP .NET MVC5官方教程总结(七)Edit方法和Edit视图详解 在本章中,我们研究生成的Edit方法和视图.但在研究之前,我们先将 release date 弄得好看一点.打开Models\Movie.cs 文件.先添加一个引用: <span style="font-size:14px;">using System.ComponentModel.DataAnnotations;</span> 然后在Movie类中添加以下代码: [Display(