希望实现的效果是:对购物车中所有商品的总价,实现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 }
);