使用MVC4,Ninject,EF,Moq,構建一個真實的應用電子商務SportsStore(二)

來源:互聯網
上載者:User
上一篇中,我們建立了一個基本的項目架構,如果你細心的去研究這個架構,你一定已經發現,我們實際上已經使用了一個領域模型代替了MVC中的model,為什麼要這麼做呢?只要是因為在MVC這個古老的三層架構中,M的本意是用來向Controller提供資料,封裝商務邏輯的,C在通過調用View來展示資料給使用者。反過來,使用者通過觸發View的某些事件來將自己的意圖傳遞給C,C再分發使用者的命令道M,去擷取使用者想要的結果。這是一種理想的狀態,在真正的項目中,經常會出現M繞過C,直接調用V,而View也會直接調用M的現象。這就導致了一種錯誤的、混亂的資料流的出現,是項目潛在風險遞增的根源。MVP就是為了克服這種現象而產生的,好了,我們不去管什麼MVP,MVVM了,現在就 言歸正傳,回到我們的項目中,繼續展示MVC的精彩與魅力。 我們知道,我們需要一些途徑或方式,去資料庫中取得Product entities。為了保持架構上的完美,我們要遵循持久邏輯與領域模型實體分離的原則,要做到這一點,我們使用repository 設計模式. 我們不需要擔心怎樣去實現持久層,我們從定義一個介面開始,去啟動它。 在Abstract檔案夾上右擊,選擇添加一個介面,命名為IProductsRepository,代碼如下:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using SportsStore.Domain.Entities;namespace SportsStore.Domain.Abstract{    public interface IProductsRepository    {        IQueryable<Product> Products { get; }    }}

這個借口使用了IQueryable<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 SportsStore.Domain.Abstract; using SportsStore.Domain.Entities; using Moq; using Ninject; namespace SportsStore.WebUI.Infrastructure{    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() {                  Mock<IProductsRepository> mock = new Mock<IProductsRepository>();                  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 }                 }.AsQueryable());                 ninjectKernel.Bind<IProductsRepository>().ToConstant(mock.Object);            }         }    } 為了使這些添加的代碼能夠正常的運行,需要添加幾個命名空間,但是我們建立Mock repository實現的過程使用了Moq技術,AsQueryable 方法是一個 LINQ 擴充方法,它轉換IEnumerable<T>進入IQueryable<T>, 這裡我們需要去匹配我們的介面簽名。無論 IProductsRepository在哪獲得了一個請求, 我們都需要Ninject去返回同樣的mock對象,這就是 為什麼我們使用ToConstant方法的原因。...ninjectKernel.Bind<IProductRepository>(). ToConstant(mock.Object);...  展示產品列表 已經做了這麼久,我們還沒有看到任何可視化的效果,這對於有些心急的朋友來說是不公平的,看不見有任何成績出來,將會打擊我們做項目的信心,這對Team Dev是很不利的事情,現在就讓我們添加一個Controller到SportsStore.WebUI工程中,選擇添加控制器,命名為ProductController,確保模板選型為空白,如:  接下來,你要刪除VS自動為你添加的代碼,並用如下代碼代替:using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using SportsStore.Domain.Abstract;using SportsStore.Domain.Entities; namespace SportsStore.WebUI.Controllers{    public class ProductController : Controller    {        private IProductsRepository repository;        public ProductController(IProductsRepository productRepository)        {            this.repository = productRepository;        }         public ViewResult List()        {            return View(repository.Products);        }     }} 如果你的工程中,using SportsStore.Domain.Abstract; 這條語句存在錯誤,你需要添加對SportsStore.Domain工程的引用,如: 現在要做的是添加一個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 元素.  設定Default Route 現在我們需要去做的,就是告訴MVC架構,當一個請求到達時,我們的網站要映射到

ProductController類的List 活動方法,這需要去修改App_Start/RouteConfig.cs檔案的

RegisterRoutes方法,代碼如下:

 using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using System.Web.Routing; namespace SportsStore.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 }            );        }    }} 完成修改後,運行你的應用,你將看到如下畫面:  你可以去下載我的源碼,地址是:http://vdisk.weibo.com/s/DS1PL/1370071350 這部分我們展示了我們應用,運用了部分Moq技術和Ninject技術,但是我們現在的資料還只是Mock對象中的類比資料,還不是真正的資料庫中的資料,下一部分,我們將引入EF架構,去領略一下ORM資料操作的風采。如果你覺得我寫的辛苦,你覺得你得到了你想要的東西,那麼請推薦它給其他有需要的人吧!請繼續關注我的續篇,精彩才剛剛開始!
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.