標籤: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 }
);