MVC扩展控制器工厂,通过继承DefaultControllerFactory来决定使用哪个接口实现,使用Ninject
希望实现的效果是:对购物车中所有商品的总价,实现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 }
);
MVC扩展控制器工厂,通过继承DefaultControllerFactory来决定使用哪个接口实现,使用Ninject的更多相关文章
- MVC扩展控制器工厂,通过实现IControllerFactory,根据action名称生成不同的Controller
关于控制器工厂的扩展,要么通过实现IControllerFactory接口,要么通过继承DefaultControllerFactory.本篇中,我想体验的是: 1.当请求经过路由,controlle ...
- MVC扩展控制器, 把部分视图转换成字符串(带验证信息), 并以json传递给前端视图
当我们使用jQuery异步提交表单数据的时候,需要把部分视图转换成字符串(带验证信息),以json的形式传递给前端视图. 使用jQuery异步加载部分视图,返回内容追加到页面某个div: jQ ...
- MVC项目实践,在三层架构下实现SportsStore-03,Ninject控制器工厂等
SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...
- .NET/ASP.NET MVC Controller 控制器(IController控制器的创建过程)
阅读目录: 1.开篇介绍 2.ASP.NETMVC IControllerFactory 控制器工厂接口 3.ASP.NETMVC DefaultControllerFactory 默认控制器工厂 4 ...
- .NET/ASP.NET MVC Controller 控制器(深入解析控制器运行原理)
阅读目录: 1.开篇介绍 2.ASP.NETMVC Controller 控制器的入口(Controller的执行流程) 3.ASP.NETMVC Controller 控制器的入口(Controll ...
- 三、ASP.NET MVC Controller 控制器(二:IController控制器的创建过程)
阅读目录: 1.开篇介绍 2.ASP.NETMVC IControllerFactory 控制器工厂接口 3.ASP.NETMVC DefaultControllerFactory 默认控制器工厂 4 ...
- 二、ASP.NET MVC Controller 控制器(一:深入解析控制器运行原理)
阅读目录: 1.开篇介绍 2.ASP.NETMVC Controller 控制器的入口(Controller的执行流程) 3.ASP.NETMVC Controller 控制器的入口(Controll ...
- NET/ASP.NET MVC Controller 控制器(一:深入解析控制器运行原理)
阅读目录: 1.开篇介绍 2.ASP.NETMVC Controller 控制器的入口(Controller的执行流程) 3.ASP.NETMVC Controller 控制器的入口(Controll ...
- ASP.NET MVC 创建控制器类过程
MvcHandler.ProcessRequestInit()方法: 1.1获取控制器的名称string requiredString = this.RequestContext.RouteData. ...
随机推荐
- 铁轨(UVa 514)
利用栈实现 C++11 代码如下: #include<iostream> #include<stack> using namespace std; #define maxn 1 ...
- day5模块学习--hashlib模块
hashlib模块 Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 什么是摘要算法呢?摘要算法又称哈希算法.散列算法.它通过一个函数,把任意长度的数据转换为一个长度 ...
- linux下根目录扩容
划分出一个磁盘,并将其格式化 [root@gg ~]# mkfs.ext3 /dev/sdb2 创建一个物理卷 [root@gg ~]# pvcreate /dev/sdb2 [roo ...
- CentOS 5.x上配置JBoss6.x步骤图解教程
1.如何远程连接CentOS和文件上传下载 使用工具Xmanager下的Xbroswer 首先在Xbroswer下的Xshell下新建文件夹JavaPlatServer,新建一个Xshell Sess ...
- 在静态方法中应用spring注入的类
最近在一次项目的重构中,原项目需要在静态方法中调用service,现在需要更换框架,service需要自动注入,无法再静态方法中调用 解决思路: 创建一个当前类的静态变量,创建一个方法,使用@Post ...
- Could not open JDBC Connection for transaction; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (Could not create connection to database server.
报错信息:Could not open JDBC Connection for transaction; nested exception is org.apache.commons.dbcp.SQL ...
- Oracle 默认的几个登陆用户名和密码
默认用户有这么几个,system,sys,scott,hr ,一般scott 和hr 作为你的练习用户.system的默认密码是 manager sys的默认密码是 change_on_install ...
- django数据库操作-增删改查-多对多关系以及一对多(外键)关系
一.一对多(外键) 例子:一个作者对应多本书,一本书只有一个作者 model代码: class Person(models.Model); name = models.CharField('作者姓名' ...
- BZOJ 1951SDOI2010 古代猪文
真是到很强的数学题 先利用欧拉定理A^B %p=A^(B%φ(p)+φ(p) ) %p 然后利用卢卡斯定理求出在modφ(p)的几个约数下的解 再利用中国剩余定理合并 计算答案即可 By:大奕哥 #i ...
- 2018 计蒜之道复赛 贝壳找房魔法师顾问(并查集+dfs判环)
贝壳找房在遥远的传奇境外,找到了一个强大的魔法师顾问.他有 22 串数量相同的法力水晶,每个法力水晶可能有不同的颜色.为了方便起见,可以将每串法力水晶视为一个长度不大于 10^5105,字符集不大于 ...