MVC擴充控制器工廠,通過繼承DefaultControllerFactory來決定使用哪個介面實現,使用Ninject

來源:互聯網
上載者:User

標籤:style   c   class   blog   code   http   

希望實現的效果是:對購物車中所有商品的總價,實現9折或8折:

 

 

當點擊"9折":

 

 

當點擊"8折":

 

□ 思路

8折或9折是打折介面的不同實現,關鍵是:由什麼條件決定使用哪種打折方式?

--當點擊8折或9折連結的時候,把參數放在路由中,然後在自訂控制器工廠中根據參數的不同選擇使用哪種打折方式。

 

□ model

    public class CartLine
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
        public int Quantity { get; set; }
    }

 

□ 介面

using MvcApplication2.Models;

namespace MvcApplication2
{
    public interface IDiscount
    {
        decimal GetFinalPrice(List<CartLine> cartLines);
    }
}

 

□ 介面的2種實現

using System.Collections.Generic;
 
namespace MvcApplication2.implementation
{
    public class NineDiscount : IDiscount
    {
        public decimal GetFinalPrice(List<Models.CartLine> cartLines)
        {
            decimal result = 0.0M;
            foreach (var item in cartLines)
            {
                result += item.Price*item.Quantity;
            }
            return result*(90M/100M);
        }
    }
}
 
 
 
using System.Collections.Generic;
 
namespace MvcApplication2.implementation
{
    public class EightDiscount : IDiscount
    {
        public decimal GetFinalPrice(List<Models.CartLine> cartLines)
        {
            decimal result = 0.0M;
            foreach (var item in cartLines)
            {
                result += item.Price * item.Quantity;
            }
            return result * (80M / 100M);
        }
    }
}
 

 

□ HomeController

using System.Collections.Generic;
using System.Web.Mvc;
using MvcApplication2.Models;
 
namespace MvcApplication2.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            List<CartLine> cartLines = new List<CartLine>()
            {
                new CartLine(){Id = 1, Name = "Product1", Price = 80M, Quantity = 2},
                new CartLine(){Id = 2, Name = "Product2", Price = 100M, Quantity = 3},
            };
            Session["cart"] = cartLines;
            return View(cartLines);
        }
 
    }
}
 

 

□ Home/Index.cshtml

把不同的打折方式放在路由中傳遞。

@model List<MvcApplication2.Models.CartLine>
 
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
 
<h2>Index</h2>
 
<table>
    <tr style="background-color: #e3e3e3;">
        <td>產品</td>
        <td>價格</td>
        <td>數量</td>
    </tr>
    @foreach (var item in Model)
    {
        <tr>
            <td>@item.Name</td>
            <td>@string.Format("{0:C}", item.Price)</td>
            <td>@item.Quantity</td>
        </tr>
    }
</table>
 
<p>
    @Html.ActionLink("9折購買", "Index", "Shop", new {policy = "Nine"},new {})
</p>
 
<p>
    @Html.ActionLink("8折購買", "Index", "Shop", new {policy = "Eight"},new {})
</p>    
 

 

□ 自訂控制器工廠,使用Ninject,根據路由參數policy的不同,決定選擇具體的打折介面實現

using System;
using System.Web.Mvc;
using System.Web.Routing;
using MvcApplication2.implementation;
using Ninject;
 
namespace MvcApplication2.Extension
{
    public class NinjectControllerFactory : DefaultControllerFactory
    {
        IKernel ninjectKernel;
        string policy = "";
 
        public NinjectControllerFactory()
        {
            ninjectKernel = new StandardKernel();
        }
 
        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            if (requestContext.RouteData.Values["policy"] != null)
            {
                policy = requestContext.RouteData.Values["policy"].ToString();
            }
            AddBindings();
            return controllerType == null ? null : (IController) ninjectKernel.Get(controllerType);
        }
 
        private void AddBindings()
        {
            switch (policy)
            {
                case "Eight":
                    ninjectKernel.Rebind<IDiscount>().To<EightDiscount>();
                    break;
                case "Nine":
                    ninjectKernel.Rebind<IDiscount>().To<NineDiscount>();
                    break;
                default:
                    ninjectKernel.Rebind<IDiscount>().To<NineDiscount>();
                    break;
            }
        }
    }
}
 

 

□ 自訂控制器工廠全域註冊

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

 

□ ShopController中使用打折介面方法

using System;
using System.Collections.Generic;
using System.Web.Mvc;
using MvcApplication2.Models;
 
 
namespace MvcApplication2.Controllers
{
    public class ShopController : Controller
    {
        public IDiscount _Discount;
 
        public ShopController(IDiscount discount)
        {
            this._Discount = discount;
        }
 
        public ActionResult Index(string policy)
        {
            List<CartLine> cartLines = new List<CartLine>();
            if (Session["cart"] != null)
            {
                cartLines = (List<CartLine>)Session["cart"];
            }
            ViewData["total"] = String.Format("{0:C}",_Discount.GetFinalPrice(cartLines));
            return View();
        }
 
    }
}
 

 

□ Shop/Index.cshtml

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
 
打折後的價格為: @ViewData["total"]


□ 自訂路由

為了讓url更直觀,符合controller/action/paramter:

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{policy}",
                defaults: new { controller = "Home", action = "Index", policy = UrlParameter.Optional }
            );

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.