7.1 开始

7.1.1 解决方案

个工程。

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 }  

            );  

     
 

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

    

      

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

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

    https://blog.csdn.net/qq_21419015/article/details/80509513 SportsStore 1.开始创建Visual Studio 解决方案和项目这里 ...

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

    https://blog.csdn.net/qq_21419015/article/details/80802931 SportsStore 1.导航 添加导航控件 如果客户能够通过产品列表进行分类导 ...

  3. ASP.NET MVC5 第4章

    参考资料<ASP.NET MVC5 高级编程>第5版 第4章 模型 本章所探讨的模型是要显示.保存.创建.更新和删除的对象. 基架指使用 MVC 提供的工具为每个模型对象的标准索引构建.创 ...

  4. 第一个 MVC 应用程序(上半部分)(《精通 ASP.NET MVC5》 的第二章)

    本章将使用 ASP.NET MVC 框架创建一个简单的数据录入应用程序. 笔者会将过程分解成一个个的步骤,以便能够看出如何构造 ASP.NET MVC 应用程序.(对于一些未进行解释的内容,笔者提供了 ...

  5. 《精通ASP.NET MVC5》第2章 第一个MVC应用程序

      控制器     public class NewHomeController : Controller     {         // GET: /NewHome/         public ...

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

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...

  7. Asp.Net MVC5入门学习系列③

    原文:Asp.Net MVC5入门学习系列③ 添加一个视图(View) 接着上篇的入门系列,上面解说添加一个简单Controller(控制器),这里我们简单的在来添加一个View(视图)来展示我们Co ...

  8. Asp.Net MVC5入门学习系列②

    原文:Asp.Net MVC5入门学习系列② 添加一个Controller(控制器) 因为我们用的是Asp.Net MVC,MVC最终还是一套框架,所以我们还是需要遵循它才能玩下去,或者说是更好的利用 ...

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

    参考资料<ASP.NET MVC5 高级编程>第5版 第5章 表单和HTML辅助方法 5.1 表单的使用 5.1.1 action 和 method 特性 默认情况下,表单发送的是 HTT ...

随机推荐

  1. MyBatis关联查询,一对一关联查询

    数据库E-R关系 实体类 public class City { Long id; String name; Long countryId; Date lastUpdate; } public cla ...

  2. Vue-router的基本用法

    刚学习vue不久,就接触了路由这个好东西.下面简单聊聊vue-router的基本用法. 一.路由的概念 路由,其实就是指向的意思,当我点击页面上的home按钮时,页面中就要显示home的内容,如果点击 ...

  3. Day25-JSONP跨域请求

    1.  json 是一种数据格式, jsonp 是一种数据调用的方式.你可以简单的理解为 带callback的json就是jsonp. 2. Python里面有个模块requests, request ...

  4. 安装完打开 eclipse 提示 JVM 版本较低

    在安装完 eclipse 后打开出现如下提示 解决办法: 1> 去官网下载最新版本安装 地址 2> linux 下直接下载安装 1.打开终端 2.控制台输入:su 3.控制台输入个人密码 ...

  5. 洛谷 P1073 最优贸易 解题报告

    P1073 最优贸易 题目描述 \(C\)国有\(n\)个大城市和\(m\)条道路,每条道路连接这\(n\)个城市中的某两个城市.任意两个城市之间最多只有一条道路直接相连.这\(m\)条道路中有一部分 ...

  6. 【bzoj3932】 CQOI2015—任务查询系统

    http://www.lydsy.com/JudgeOnline/problem.php?id=3932 (题目链接) 题意 给出$m$个区间,每个区间有一个权值,$n$组询问,每次询问在位置$x$权 ...

  7. 洛谷P2672 推销员

    沙雕贪心...... 我一开始想的是倒着来,每次减去一个. 然后我们就有两个决策:去掉最后一个/去掉前面某一个. 然后第一个决策用并查集维护,第二个决策用线段树即可.仔细想想觉得普及组不会考这种东西, ...

  8. asp.net中SQL语句太长,怎么换行写?

    http://bbs.csdn.net/topics/390639485?page=1 string strfac="insert into CarInfo values('"+T ...

  9. adb logcat介绍

    logcat命令语法: [adb] logcat [<option>] ... [<filter-spec>] ... adb logcat -c 清除所有以前的日志 adb ...

  10. 一个ssm综合小案例-商品订单管理----写在前面

    学习了这么久,一直都是零零散散的,没有把知识串联起来综合运用一番 比如拦截器,全局异常处理,json 交互,RESTful 等,这些常见技术必须要掌握 接下来呢,我就打算通过这么一个综合案例把这段时间 ...