MVC項目實踐,在三層架構下實現SportsStore-03,Ninject控制器工廠等


SportsStore是《精通ASP.NET MVC3框架(第三版)》中演示的MVC項目,在該項目中涵蓋了MVC的眾多方面,包括:使用DI容器、URL優化、導航、分頁、購物車、訂單、產品管理、圖像上傳......是不錯的MVC實踐項目,但該項目不是放在多層框架下開發的,離真實項目還有一段距離。本系列將嘗試在多層框架下實現SportsStore項目,並用自己的方式實現一些功能。

 

本篇為系列第三篇,包括:

■ 5、自定義Ninject控制器工廠
■ 6、項目的第一次運行

 

  5、自定義Ninject控制器工廠

在MySportsStore.WebUI下添加如下引用:

● 添加對Ninject的引用
● 添加對MySportsStore.IBLL的引用
● 添加對MySportsStore.BLL的引用
● 添加對MySportsStore.Model的引用


創建NinjectControllerFactory:

using System.Web.Mvc;
using MySportsStore.BLL;
using MySportsStore.IBLL;
using Ninject;

namespace MySportsStore.WebUI.Extension
{
    public class NinjectControllerFactory : DefaultControllerFactory
    {
        private IKernel ninjectKernel;

        public NinjectControllerFactory()
        {
            ninjectKernel = new StandardKernel();
            AddBindings();
        }

        protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, System.Type controllerType)
        {
            return controllerType == null ? null : (IController) ninjectKernel.Get(controllerType);
        }

        private void AddBindings()
        {
            ninjectKernel.Bind<IProductService>().To<ProductService>();
        }
    }
}

在全局中注冊NinjectControllerFactory
public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            ......

            ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
        }
    }


為什么需要NinjectControllerFactory?
Ninject這個DI容器可以幫我們很好地管理接口和實現,並且以屬性或構造函數的形式注入到控制器中,從而調用接口實現類的方法。並且,Ninject提供了Get()方法,使得使用Ninject也可以創建Controller。

 

  6、項目的第一次運行

創建BaseController,其中賦予手動垃圾回收的機制。

using System;
using System.Collections.Generic;
using System.Web.Mvc;

namespace MySportsStore.WebUI.Controllers
{
    public class BaseController : Controller
    {
        protected IList<IDisposable> DisposableObjects { get; private set; }

        public BaseController()
        {
            this.DisposableObjects = new List<IDisposable>();
        }

        protected void AddDisposableObject(object obj)
        {
            IDisposable disposable = obj as IDisposable;
            if (disposable != null)
            {
                this.DisposableObjects.Add(disposable);
            }
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                foreach (IDisposable obj in this.DisposableObjects)
                {
                    if (null != obj)
                    {
                        obj.Dispose();
                    }
                }
            }
            base.Dispose(disposing);
        }
    }
}

當其它的Controller派生於BaseController時,如果用到類型為IXXXService的XXXService,就通過BaseController的AddDisposableObject(object obj)把該XXXService放到BaseController中的DisposableObjects集合屬性中,在使用Dispose()銷毀這些XXXService。

 

而在BaseService中也提供了手動垃圾回收機制,可以及時回收CurrentRepository。

 

最后在BaseRepository中也提供了手動垃圾回收機制,可以及時回收EF上下文。

 

創建ProductController,使之派生於BaseController:

using System.Web.Mvc;
using MySportsStore.IBLL;
using Ninject;

namespace MySportsStore.WebUI.Controllers
{
    public class ProductController : BaseController
    {
        [Inject]
        IProductService ProductService { get; set; }

        public ProductController()
        {
            this.AddDisposableObject(ProductService);
        }

        public ViewResult List()
        {
            return View(ProductService.LoadEntities(p => true).AsQueryable());
        }
    }
}

對應的Prduct/List.cshtml視圖為:

@model IEnumerable<MySportsStore.Model.Product>

@{
    ViewBag.Title = "List";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@foreach (var item in Model)
{
    <div class="item">
        <h3>@item.Name</h3>
        @item.Description
        <h4>@item.Price.ToString("c")</h4>
    </div>
}

為了能夠讓EF在第一次運行的時候自動創建數據庫並顯示,我們還需要在MySportsStore.WebUI中的Web.config中配置連接字符串:

<connectionStrings>
    ......
    <add name="conn"
       connectionString="Data Source=.;User=some user name;Password=some password;Initial Catalog=MySportsStore;Integrated Security=True"
       providerName="System.Data.SqlClient"/>
  </connectionStrings>


修改默認路由為:

routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Product", action = "List", id = UrlParameter.Optional }
            );

運行,得到如下界面:

5

 

在數據庫中也新增了MySportsStore數據庫:

6

源碼在這里

 

“MVC項目實踐,在三層架構下實現SportsStore”系列包括:

MVC項目實踐,在三層架構下實現SportsStore,從類圖看三層架構

MVC項目實踐,在三層架構下實現SportsStore-01,EF Code First建模、DAL層等

MVC項目實踐,在三層架構下實現SportsStore-02,DbSession層、BLL層

MVC項目實踐,在三層架構下實現SportsStore-03,Ninject控制器工廠等

MVC項目實踐,在三層架構下實現SportsStore-04,實現分頁

MVC項目實踐,在三層架構下實現SportsStore-05,實現導航

MVC項目實踐,在三層架構下實現SportsStore-06,實現購物車

MVC項目實踐,在三層架構下實現SportsStore-07,實現訂單提交

MVC項目實踐,在三層架構下實現SportsStore-08,部署到IIS服務器

MVC項目實踐,在三層架構下實現SportsStore-09,ASP.NET MVC調用ASP.NET Web API的查詢服務

MVC項目實踐,在三層架構下實現SportsStore-10,連接字符串的加密和解密

MVC項目實踐,在三層架構下實現SportsStore-11,使用Knockout實現增刪改查


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM