zoukankan      html  css  js  c++  java
  • 第7章 SportsStorePeta 一个真实的应用程序

    SportsStorePeta应用程序开发

    步骤:

      1.创建解决方案和项目(Domain、WebUI、UnitTests)

      2.添加引用

      3.设置ID容器

      4.设计域模型

      5.创建抽象存储库

      6.创建模仿存储库

      7.添加控制器、动作及视图

      8.设置路由

      9.准备数据库及数据表

      10.创建实例框架上下文

      11.创建产品存储库

      12.添加分页

      13.改进路由及URL

      14.设置内容样式CSS

      15.创建分部视图 

    一、解决方案:SportsStorePeta,该应用程序将不使用EF,而使用PetaPoco实现

      项目:

     

    二、项目引用

      项目及依赖性

    项目名 VS模板 目的 工具依赖 项目依赖 微软引用
    SportsStorePeta.Domain 类库 存放域实体与逻辑,EF None None

    System.Web.Mvc

    System.ComponentModel.DataAnnotations

    SportsStorePeta.WebUI Asp.net MVC4 应用程序  Basic(基本) 存放控制器与视图 

    Ninject

    Moq

    SportsStorePeta.Domain None
    SportsStorePeta.UnitTests  测试项目 单元测试

    Ninject

    Moq

    SportsStorePeta.Domain

    SportsStorePeta.WebUI

    System.Web.Mvc

    System.Web

    Microsoft.CSharp

    三、设置ID容器

      1.Ninject控制器工厂: 

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Routing;
    using Ninject;
    
    namespace SportsStorePeta.WebUI.Infrastructure
    {
        /// <summary>
        /// 使用Ninject修改默认控制器工厂 
        /// </summary>
        public class NinjectControllerFactory  :DefaultControllerFactory
        {
            private readonly 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()
            {
                //Ninject绑定
            }
        }
    }

      MVC框架注册NinjectControllerFactory

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Http;
    using System.Web.Mvc;
    using System.Web.Optimization;
    using System.Web.Routing;
    using SportsStorePeta.WebUI.Infrastructure;
    
    namespace SportsStorePeta.WebUI
    {
        // 注意: 有关启用 IIS6 或 IIS7 经典模式的说明,
        // 请访问 http://go.microsoft.com/?LinkId=9394801
    
        public class MvcApplication : System.Web.HttpApplication
        {
            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
    
                WebApiConfig.Register(GlobalConfiguration.Configuration);
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                BundleConfig.RegisterBundles(BundleTable.Bundles);
    
                //MVC框架注册NinjectControllerFactory
                ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
            }
        }
    }

     四、设计域模型 和视图模型

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace SportsStorePeta.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; }
        }
    }

          视图模型

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace SportsStorePeta.WebUI.Models
    {
        public class ProductViewModel
        {
            public int ProductId { get; set; }
            public string Name { get; set; }
            public string Description { get; set; }
            public string Price { get; set; }
            public string Category { get; set; }
        }
    }

    五、创建抽象存储库 

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using SportsStorePeta.Domain.Entities;
    
    namespace SportsStorePeta.Domain.Abstract
    {
       public interface IProductRepository
        {
           IQueryable<Product> Products { get; } 
        }
    }

    六、创建模仿存储库

    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 SportsStorePeta.Domain.Abstract;
    using SportsStorePeta.Domain.Entities;
    
    namespace SportsStorePeta.WebUI.Infrastructure
    {
        /// <summary>
        /// 使用Ninject修改默认控制器工厂 
        /// </summary>
        public class NinjectControllerFactory  :DefaultControllerFactory
        {
            private readonly 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()
            {
                //Ninject绑定
                //1.添加模拟IproductRepository实现
                Mock<IProductRepository> mock=new Mock<IProductRepository>();
                mock.Setup(m => m.Products).Returns(
                    new List<Product>
                    {
                        new Product {Name = "Football", Price = 35},
                        new Product {Name = "Surf board", Price = 179},
                        new Product {Name = "Running shoes", Price = 87}
                    }.AsQueryable());
                //永久绑定
                _ninjectKernel.Bind<IProductRepository>().ToConstant(mock.Object);
            }
        }
    }

    七、添加控制器、动作及视图

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using SportsStorePeta.Domain.Abstract;
    using SportsStorePeta.Domain.Entities;
    using SportsStorePeta.WebUI.Models;
    
    namespace SportsStorePeta.WebUI.Controllers
    {
        public class ProductController : Controller
        {
            private readonly IProductRepository _repository;
    
            public ProductController(IProductRepository productRepository)
            {
                _repository = productRepository;
            }
    
            public ViewResult List()
            {
                List<ProductViewModel> productViewModels = new List<ProductViewModel>();
                foreach (Product product in _repository.Products)
                {
                    ProductViewModel productViewModel = new ProductViewModel
                    {
                        ProductId = product.ProductId,
                        Name = product.Name,
                        Description = product.Description,
                        Price = product.Price,
                        Category = product.Category
                    };
                    productViewModels.Add(productViewModel);
                }
    
                return View(productViewModels);
    
            }
        }
    }

      视图

    @model IEnumerable<SportsStorePeta.WebUI.Models.ProductViewModel>
    @{
        ViewBag.Title = "商品";
    }
    
    @foreach (var p in Model)
    {
        <div class="item">
            <h3>@p.Name</h3>
            @p.Description
            <h4>@p.Price</h4>
        </div>
    }

    八、设置路由

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Routing;
    
    namespace SportsStorePeta.WebUI
    {
        public class RouteConfig
        {
            public static void RegisterRoutes(RouteCollection routes)
            {
                routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
                routes.MapRoute(
                    name: "Default",
                    url: "{controller}/{action}/{id}",
                    defaults: new { controller = "Product", action = "List", id = UrlParameter.Optional }
                );
            }
        }
    }

    九、准备数据库及数据表

    建表SQL语句

    Create table Products(
      [ProductId] INT NOT NULL PRIMARY KEY IDENTITY,
      [Name] NVARCHAR(100) NOT NULL,
      [Description]  NVARCHAR(500) NOT NULL,   
      [Category] NVARCHAR(50) NOT NULL,
      [Price] DECIMAL(16,2) NOT NULL         
    )

    表建好后,可以插入一些数据做显示用。

    INSERT INTO [Products] ([Name],[Description],[Category],[Price]) VALUES (N'Lifejacket',N'Protective and fashionbale',N'Watersports',48.95);
    INSERT INTO [Products] ([Name],[Description],[Category],[Price]) VALUES (N'Soccer Ball',N'FIFA-approved size and weight',N'Soccer',19.50);
    INSERT INTO [Products] ([Name],[Description],[Category],[Price]) VALUES (N'CornerFlags',N'Give your playing field a protessional ',N'Soccer',34.50);
    INSERT INTO [Products] ([Name],[Description],[Category],[Price]) VALUES (N'蓝球',N'CornerFlagssafasdfsdf',N'Soccer',34.20);
    INSERT INTO [Products] ([Name],[Description],[Category],[Price]) VALUES (N'CornerFlags12',N'CornerFlagssafasdfsdf',N'Soccer',43.20);
    INSERT INTO [Products] ([Name],[Description],[Category],[Price]) VALUES (N'CornerFlags13',N'CornerFlagssafasdfsdf',N'Soccer',11.23);
    INSERT INTO [Products] ([Name],[Description],[Category],[Price]) VALUES (N'CornerFlags14',N'CornerFlagssafasdfsdf',N'Soccer',123.23);
    INSERT INTO [Products] ([Name],[Description],[Category],[Price]) VALUES (N'CornerFlagssafasdfsdf',N'CornerFlagssafasdfsdf',N'Soccer',32.23);

    十、创建实例框架上下文

      1.NuGet中引入PetaPoco

      2.web.config添加数据库连接

     <connectionStrings>
        <add name="DbContext" providerName="System.Data.SqlClient" connectionString="Data Source=(localdb)v11.0;Initial Catalog=SportsStore;Integrated Security=True" />
      </connectionStrings>

      3.设置PetaPoco,修改DataBase.tt模板

        ConnectionStringName = "DbContext";            
        Namespace = "SportsStorePeta.Domain.Entities";

       修改PetaPoco.Core.ttinclude 

    <#@ template language="C#" hostspecific="True" #>

      4.新建上下文类:PpDbContext

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using SportsStorePeta.Domain.Entities;
    
    namespace SportsStorePeta.Domain.Concrete
    {
        public class PpContext : DbContextDB
        {
            public IQueryable<Product> Products
            {
                get
                {
                    var products = base.Query<Product>("Select ProductId,Name,Description,Category,Price from Products").AsQueryable();
                    return products;
                }
            } 
        }
    }

    十一、创建产品存储库PpProductRepository

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using SportsStorePeta.Domain.Abstract;
    using SportsStorePeta.Domain.Entities;
    
    namespace SportsStorePeta.Domain.Concrete
    {
       public class PpProductRepository :IProductRepository
        {
           private readonly PpContext _context=new PpContext();
           public IQueryable<Product> Products
           {
               get { return _context.Products; }
           }
        }
    }

      修改Ninject绑定: 

     private void AddBindings()
            {
               _ninjectKernel.Bind<IProductRepository>().To<PpProductRepository>();
            }

    十二、添加分页

       修改ProductController

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using SportsStorePeta.Domain.Abstract;
    using SportsStorePeta.Domain.Entities;
    using SportsStorePeta.WebUI.Models;
    
    namespace SportsStorePeta.WebUI.Controllers
    {
        public class ProductController : Controller
        {
            private readonly IProductRepository _repository;
            public int PageSize = 4;
    
            public ProductController(IProductRepository productRepository)
            {
                _repository = productRepository;
            }
    
            public ViewResult List(int page=1)
            {
                List<ProductViewModel> productViewModels = new List<ProductViewModel>();
                foreach (Product product in _repository.Products)
                {
                    ProductViewModel productViewModel = new ProductViewModel
                    {
                        ProductId = product.ProductId,
                        Name = product.Name,
                        Description = product.Description,
                        Price = product.Price,
                        Category = product.Category
                    };
                    productViewModels.Add(productViewModel);
                }
    
                return View(productViewModels.OrderBy(p => p.ProductId).Skip((page - 1)*PageSize).Take(PageSize));
    
            }
        }
    }

      1.添加分页视图模型 

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace SportsStorePeta.WebUI.Models
    {
        public class PageInfo
        {
            public int TotalItems { get; set; }
            public int ItemsPerPage { get; set; }
            public int CurrentPage { get; set; }
    
            public int TotalPages
            {
                get { return (int) Math.Ceiling((decimal) TotalItems/ItemsPerPage); }
            }
        }
    }

      2.添加HTML辅助器方法

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Web;
    using System.Web.Mvc;
    using SportsStorePeta.WebUI.Models;
    
    namespace SportsStorePeta.WebUI.HtmlHelpers
    {
        public static class PagingHelpers
        {
            public static MvcHtmlString PageLinks(this HtmlHelper html, PageInfo pageInfo, Func<int, string> pageUrl)
            {
                StringBuilder result = new StringBuilder();
                for (int i = 1; i < pageInfo.TotalPages; i++)
                {
                    TagBuilder tag=new TagBuilder("a");
                    tag.MergeAttribute("href",pageUrl(i));
                    tag.InnerHtml = i.ToString();
                    if (i == pageInfo.CurrentPage)
                    {
                        tag.AddCssClass("selected");
                    }
                    result.Append(tag.ToString());
                }
                return MvcHtmlString.Create(result.ToString());
            }
        }
    }

      3.修改Views/Web.config

          <namespaces>
            <add namespace="System.Web.Mvc" />
            <add namespace="System.Web.Mvc.Ajax" />
            <add namespace="System.Web.Mvc.Html" />
            <add namespace="System.Web.Optimization"/>
            <add namespace="System.Web.Routing" />
            <add namespace="SportsStorePeta.WebUI.HtmlHelpers"/>
          </namespaces>

      4.添加视图模型数据 ProductsListViewModel 

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace SportsStorePeta.WebUI.Models
    {
        public class ProductsListViewModel
        {
            public IEnumerable<ProductViewModel> Products { get; set; }
            public PageInfo PagingInfo { get; set; }
        }
    }

      5.更新List动作

      添加新方法处理域模型

           /// <summary>
            /// 根据Product域模型集合获得视图模型集合
            /// </summary>
            /// <param name="products"></param>
            /// <returns></returns>
            private IEnumerable<ProductViewModel> GetProductViewModelListByProducts(IQueryable<Product> products)
            {
                List<ProductViewModel> productsViewModels = new List<ProductViewModel>();
                foreach (Product product in products)
                {
                    ProductViewModel productViewModel = new ProductViewModel()
                    {
                        ProductId = product.ProductId,
                        Name = product.Name,
                        Category = product.Category,
                        Description = product.Description,
                        Price = product.Price.ToString("C")
                    };
                    productsViewModels.Add(productViewModel);
                }
                return productsViewModels;
            }
            public ViewResult List(int page=1)
            {
    
                ProductsListViewModel model = new ProductsListViewModel
                {
                    Products = GetProductViewModelListByProducts( _repository.Products.OrderBy(p => p.ProductId).Skip((page - 1)*PageSize).Take(PageSize)),
                    PagingInfo = new PageInfo { CurrentPage = page,ItemsPerPage = PageSize,TotalItems = _repository.Products.Count()}
                };
    
                return View(model);
            }

      6.更新List.cshtml视图

    @model SportsStorePeta.WebUI.Models.ProductsListViewModel
    @{
        ViewBag.Title = "商品";
    }
    
    @foreach (var p in Model.Products)
    {
        <div class="item">
            <h3>@p.Name</h3>
            @p.Description
            <h4>@p.Price</h4>
        </div>
    }
    
    <div class="pager">
        @Html.PageLinks(Model.PagingInfo,x=>Url.Action("List",new{page=x}))
    </div>

    十三、改进路由及URL

     public static void RegisterRoutes(RouteCollection routes)
            {
                routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
                routes.MapRoute(
                    name: null,
                    url: "Page{page}",
                    defaults: new {controller = "Product", action = "List"});
    
                routes.MapRoute(
                    name: "Default",
                    url: "{controller}/{action}/{id}",
                    defaults: new { controller = "Product", action = "List", id = UrlParameter.Optional }
                );
            }

    十四、设置内容样式CSS

      1.定义布局模板视图_Layout.cshtml

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width" />
        <title>@ViewBag.Title</title>
        <link href="/Content/Site.css" type="text/css" rel="stylesheet"/>
    </head>
    <body>
    <div id="header">
        <div class="title">体育用品</div>
    </div>
    <div id="categories">
        商品类别
    </div>
    <div id="content">
        @RenderBody()
    </div>
    </body>
    </html>

      2.添加CSS样式

      在site.css 最下面增加:

    BODY { font-family: Cambria, Georgia, "Times New Roman"; margin: 0; }
    DIV#header DIV.title, DIV.item H3, DIV.item H4, DIV.pager A {
        font: bold 1em "Arial Narrow", "Franklin Gothic Medium", Arial;
    }
    DIV#header { background-color: #444; border-bottom: 2px solid #111; color: White; }
    DIV#header div.title { font-size: 2em; padding: .6em; }
    DIV#content { border-left: 2px solid gray; margin-left: 9em; padding: 1em; }
    DIV#categories { float: left; width: 8em; padding: .3em; }
    
    DIV.item { border-top: 1px dotted gray; padding-top: .7em; margin-bottom: .7em; }
    DIV.item:first-child { border-top:none; padding-top: 0; }
    DIV.item H3 { font-size: 1.3em; margin: 0 0 .25em 0; }
    DIV.item H4 { font-size: 1.1em; margin:.4em 0 0 0; }
    
    DIV.pager { text-align:right; border-top: 2px solid silver;
        padding: .5em 0 0 0; margin-top: 1em; }
    DIV.pager A { font-size: 1.1em; color: #666; text-decoration: none;
          padding: 0 .4em 0 .4em; }
    DIV.pager A:hover { background-color: Silver; }
    DIV.pager A.selected { background-color: #353535; color: White; }

    十五、创建分部视图 

      分部视图是嵌入在另一个视图中的一个内容片段。是自包含文件,可以跨视图重用。

      1.在Shared中添加分部视图ProductSummary.cshtml

    @model SportsStorePeta.WebUI.Models.ProductViewModel
    
    <div class="item">
        <h3>@Model.Name</h3>
        @Model.Description
        <h4>@Model.Price</h4>
    </div>

      2.修改List.cshtml  

    @model SportsStorePeta.WebUI.Models.ProductsListViewModel
    @{
        ViewBag.Title = "商品";
    }
    
    @foreach (var p in Model.Products)
    {
        Html.RenderPartial("ProductSummary",p);
    }
    
    <div class="pager">
        @Html.PageLinks(Model.PagingInfo,x=>Url.Action("List",new{page=x}))
    </div>
  • 相关阅读:
    QT 图形视图框架
    QSting, QChar, char等的转换
    ucosii(2.89)mbox 应用要点
    ucosii(2.89)semaphore 应用要点
    ucosii(2.89)mutex 应用要点
    ucosii(2.89) 在Lpc1765移植中定时器的使用。
    c++中虚函数的需要性,虚析构函数的必要性
    转 在Qt中用QAxObject来操作Excel
    关于 QObject 类
    关于sigleton模式
  • 原文地址:https://www.cnblogs.com/wjs5943283/p/4614655.html
Copyright © 2011-2022 走看看