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实现增删改查

你可能感兴趣的:(inject)