ASP.NET MVC 控制器激活(二)
ASP.NET MVC 控制器激活(二)
前言
在之前的篇幅中,用文字和图像来表示了控制器的激活过程,描述的角度都是从框架默认实现的角度去进行描述的,这样也使得大家都可以清楚的知道激活的过程以及其中涉及到的对象模型,今天的篇幅就是在激活的过程中,框架提供了哪些可注入点,站在一个使用者的角度来进行描述。
激活控制器-注入点入口

如上图,这是上个篇幅中描述的控制器激活过程图,这里引用过来是怕有的朋友忘记了前面的所说和没看过前面篇幅的朋友。
就从默认控制器工厂的实现来看,在CreateController()方法中,通过GetControllerType()方法来获取控制器类型(Type),然后传递到GetControllerInstance()方法中,通过其中的实现来完成根据控制器类型(Type)到IController的生成。而在后续的注入点也是在GetControllerInstance()方法实现中来进行注入的,GetControllerInstance()方法即是整个控制器激活过程的入口点。
IoC示例
既然说到了动态注入,想必就要用到IoC框架了,在MVC学前篇中提到过Ninject的使用,下面这个示例便是依赖于Ninject的来做的演示:
/// <summary>
/// 产品实体类
/// </summary>
public class Product
{
public string ID { get; set; }
public string Name { get; set; }
}
定义一个数据实体类没什么好说的,
/// <summary>
/// 抽象数据提取库
/// </summary>
public interface IDataStandard
{
List<Product> GetProducts();
}
/// <summary>
/// 默认实现--数据提取库
/// </summary>
public class DataProvide : IDataStandard
{ public List<Product> GetProducts()
{
List<Product> products = new List<Product>()
{
new Product(){ ID="",Name="name1"},
new Product(){ID="",Name="name2"},
new Product(){ID="",Name="name3"}
};
return products;
}
}
这里定义的一个是抽象的数据提取库,和一个默认的实现作为演示用于提供数据用的。
/// <summary>
/// 抽象数据调用
/// </summary>
public interface IDataCall
{
void WriterToMonitor();
} /// <summary>
/// 默认的数据调用实现
/// </summary>
public class DefultDataCall:IDataCall
{
private IDataStandard _DataStandard; public DefultDataCall(IDataStandard dataStandard)//使用构造函数方式注入 通过Ninject框架实现
{
_DataStandard = dataStandard;
} public void WriterToMonitor()
{
foreach(var data in _DataStandard.GetProducts())
{
Console.WriteLine("Prodcut ID:" + data.ID + " Name:" + data.Name);
}
}
}
这里定义的是抽象的数据调用和默认的实现,我们现在要做的就是通过IoC框架来让调用客户端对数据调用和数据提取解耦,
class Program
{
static void Main(string[] args)
{
IKernel ninject = new StandardKernel();
ninject.Bind<IDataStandard>().To<DataProvide>();
IDataCall dataCall = ninject.Get(typeof(DefultDataCall)) as IDataCall;
if (dataCall != null)
{
dataCall.WriterToMonitor();
} Console.ReadLine();
}
}
运行这段代码:

很简单明了的一个示例,在MVC的项目中也是这样运行的。
MVC项目中的运用
在上面的章节里说过,入口点在protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType);方法中,我们只需要实现一个默认的控制器工厂类型,并且重写一下这个方法,因为我们已经可以在重写的方法中获取到控制器的类型了,有了它就可以按照IoC示例中的那样来进行其它对象到控制器的一个动态注入。
我们先要定义一个控制器,并且要让它对上述示例中的抽象提取库依赖,采取构造函数式注入(依赖)。
看一下示例:
public class IoCDemoController : Controller
{
//
// GET: /IoCDemo/ private IDataStandard _DataStandard; public IoCDemoController(IDataStandard dataStandard)
{
_DataStandard = dataStandard;
} public ActionResult Index()
{
return View(_DataStandard.GetProducts());
}
}
在Index方法上右键,点击添加视图:

点击添加,并且在视图中输入如下代码:
@model IEnumerable<ConsoleApplication2.Product>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
@foreach (var item in Model)
{
<h3>ID: @item.ID Name:@item.Name</h3>
}
再把Global.asax文件中的路由设置修改一下:
routes.MapRoute(
"Default", // 路由名称
"{controller}/{action}/{id}", // 带有参数的 URL
new { controller = "IoCDemo", action = "Index", id = UrlParameter.Optional } // 参数默认值
);
这个时候准备工作都做好,可是控制器中所用的数据哪里来呢?从我们默认实现的控制器工厂中来:
public class NinjectControllerFactory :DefaultControllerFactory
{
private IKernel _NinjectKernel; public NinjectControllerFactory()
{
_NinjectKernel = new StandardKernel();
_NinjectKernel.Bind<IDataStandard>().To<DataProvide>();
} protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
{
IController controller = _NinjectKernel.Get(controllerType) as IController;
if (controller != null)
{
return controller;
}
return null;
} }
按照上面章节中的样式,在NinjectControllerFactory中事先绑定数据类型,等到系统执行需要用到控制器的时候会通过Ninject框架来讲数据动态的注入到控制器中。
最后还要设置一项:
在Global.asax文件中的Application_Start()方法中要把我们默认的实现的控制器工厂设置到MVC框架中,
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
}
添加上代码的最后一句。现在我们就可以来看一下最终效果了。

本篇就讲到这里,会在下个篇幅中继续讲解其他的注入点。
作者:金源
出处:http://www.cnblogs.com/jin-yuan/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面
ASP.NET MVC 控制器激活(二)的更多相关文章
- 使用Code First建模自引用关系笔记 asp.net core上使用redis探索(1) asp.net mvc控制器激活全分析 语言入门必学的基础知识你还记得么? 反射
使用Code First建模自引用关系笔记 原文链接 一.Has方法: A.HasRequired(a => a.B); HasOptional:前者包含后者一个实例或者为null HasR ...
- ASP.NET MVC 控制器激活(一)
ASP.NET MVC 控制器激活(一) 前言 在路由的篇章中讲解了路由的作用,讲着讲着就到了控制器部分了,从本篇开始来讲解MVC中的控制器,控制器是怎么来的?MVC框架对它做了什么?以及前面有的篇幅 ...
- ASP.NET MVC 控制器激活(三)
ASP.NET MVC 控制器激活(三) 前言 在上个篇幅中说到从控制器工厂的GetControllerInstance()方法来执行控制器的注入,本篇要讲是在GetControllerInstanc ...
- asp.net mvc控制器激活全分析
控制器的激活默认情况下使用反射来实现的,这其中采用了DI,单例等设计模式.对于控制器的主要涉及到如下的类:ControllerBuilder.DefaultControllerFactory.Defa ...
- MVC 控制器激活
MVC 控制器激活 ASP.NET MVC 控制器激活(三) 前言 在上个篇幅中说到从控制器工厂的GetControllerInstance()方法来执行控制器的注入,本篇要讲是在GetControl ...
- 学习ASP.NET MVC(二)——我的第一个ASP.NET MVC 控制器
MVC全称是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,是一种软件设计典范,用一种业务逻辑和数据显示分离的方法组织代码,将 ...
- ASP.NET MVC 描述类型(二)
ASP.NET MVC 描述类型(二) 前言 上个篇幅中说到ControllerDescriptor类型的由来过程,对于ControllerDescriptor类型来言ActionDescriptor ...
- ASP.NET MVC Model验证(二)
ASP.NET MVC Model验证(二) 前言 上篇内容演示了一个简单的Model验证示例,然后在文中提及到Model验证在MVC框架中默认所处的位置在哪?本篇就是来解决这个问题的,并且会描述一下 ...
- ASP.NET MVC Model绑定(二)
ASP.NET MVC Model绑定(二) 前言 上篇对于Model绑定的简单演示想必大家对Model绑定的使用方式有一点的了解,那大家有没有想过Model绑定器是在什么时候执行的?又或是执行的过程 ...
随机推荐
- RPC框架性能基本比较测试
RPC框架:gRPC.Thrift.Wildfly.Dubbo 原文链接:http://www.open-open.com/lib/view/open1426302068107.html gRPC是G ...
- ROS学习(二)—— 配置ROS环境
一.管理环境 p { margin-bottom: 0.25cm; line-height: 120% } a:link { } 如果你在查找和使用ROS软件包方面遇到了问题,请确保你已经正确配置了脚 ...
- 收集常用的.net开源项目
Json.NET http://json.codeplex.com/ Json.NET是一个读写Json效率比较高的.Net框架.Json.Net 使得在.Net环境下使用Json更加简单.通过Lin ...
- WebGL入门教程(二)-webgl绘制三角形
前面已经介绍过了webgl,WebGL入门教程(一)-初识webgl(http://www.cnblogs.com/bsman/p/6128447.html),也知道了如何绘制一个点,接下来就用web ...
- ctf汇总
IDF实验室:牛刀小试 IDF实验室:倒行逆施 linux shell 常用指令 汇编笔记 堆栈溢出
- 《DSP using MATLAB》示例Example5.19
代码: n = 0:9; x = n+1; h = [1,0,-1]; N = 6; y = ovrlpsav(x,h,N); nh = 0:1:length(h)-1; ny = 0:1:lengt ...
- [spring源码学习]三、IOC源码——自定义配置文件读取
一.环境准备 在文件读取的时候,第9步我们发现spring会根据标签的namespace来选择读取方式,联想spring里提供的各种标签,比如<aop:xxx>等应该会有不同的读取和解析方 ...
- C#ListBox对Item进行重绘,包括颜色
别的不多说了,上代码,直接看 首先设置这行,或者属性窗口设置,这样才可以启动手动绘制,参数有三个 Normal: 自动绘制 OwnerDrawFixed:手动绘制,但间距相同 OwnerDrawVar ...
- Json格式示意图
json视图工具:http://www.bejson.com/jsonviewernew/ 一.Json格式化,(看到数组里面又有数组一下子疑问不是合格json):尾门地址查询: =>=> ...
- css定位学习经验记录
之前了解到css的定位position属性,常用的三种: position:absolute 1.当父元素定位为relative时,以父元素为起始坐标定位. 2.当父元素没有定位时,以body为起始坐 ...