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 控制器激活(二)的更多相关文章

  1. 使用Code First建模自引用关系笔记 asp.net core上使用redis探索(1) asp.net mvc控制器激活全分析 语言入门必学的基础知识你还记得么? 反射

    使用Code First建模自引用关系笔记   原文链接 一.Has方法: A.HasRequired(a => a.B); HasOptional:前者包含后者一个实例或者为null HasR ...

  2. ASP.NET MVC 控制器激活(一)

    ASP.NET MVC 控制器激活(一) 前言 在路由的篇章中讲解了路由的作用,讲着讲着就到了控制器部分了,从本篇开始来讲解MVC中的控制器,控制器是怎么来的?MVC框架对它做了什么?以及前面有的篇幅 ...

  3. ASP.NET MVC 控制器激活(三)

    ASP.NET MVC 控制器激活(三) 前言 在上个篇幅中说到从控制器工厂的GetControllerInstance()方法来执行控制器的注入,本篇要讲是在GetControllerInstanc ...

  4. asp.net mvc控制器激活全分析

    控制器的激活默认情况下使用反射来实现的,这其中采用了DI,单例等设计模式.对于控制器的主要涉及到如下的类:ControllerBuilder.DefaultControllerFactory.Defa ...

  5. MVC 控制器激活

    MVC 控制器激活 ASP.NET MVC 控制器激活(三) 前言 在上个篇幅中说到从控制器工厂的GetControllerInstance()方法来执行控制器的注入,本篇要讲是在GetControl ...

  6. 学习ASP.NET MVC(二)——我的第一个ASP.NET MVC 控制器

    MVC全称是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,是一种软件设计典范,用一种业务逻辑和数据显示分离的方法组织代码,将 ...

  7. ASP.NET MVC 描述类型(二)

    ASP.NET MVC 描述类型(二) 前言 上个篇幅中说到ControllerDescriptor类型的由来过程,对于ControllerDescriptor类型来言ActionDescriptor ...

  8. ASP.NET MVC Model验证(二)

    ASP.NET MVC Model验证(二) 前言 上篇内容演示了一个简单的Model验证示例,然后在文中提及到Model验证在MVC框架中默认所处的位置在哪?本篇就是来解决这个问题的,并且会描述一下 ...

  9. ASP.NET MVC Model绑定(二)

    ASP.NET MVC Model绑定(二) 前言 上篇对于Model绑定的简单演示想必大家对Model绑定的使用方式有一点的了解,那大家有没有想过Model绑定器是在什么时候执行的?又或是执行的过程 ...

随机推荐

  1. 前端弹出层框架layer

    http://www.layui.com/doc/modules/layer.html#layer.confirm

  2. 电脑只有网页打不开,QQ和其他软件都能用

    应该就是浏览器设置代理服务器的问题 1.打开浏览器->找到工具->internet选项->链接->局域网设置 将代理服务器下面勾去掉

  3. nodejs复习01

    console 格式化 console.log("%s:%s", "a", "b") //字符串 console.log("%d. ...

  4. 公共资源情报(OSINT)工具Automater

    公共资源情报(OSINT)工具Automater   公共资源情报(OSINT)就是从公共信息中提取有用情报.它是美国中央情报局(CIA)的一种情报搜集手段,各国都在广泛利用这种方式.Kali Lin ...

  5. lamp

      Linux+Apache+Mysql/MariaDB+Perl/PHP/Python一组常用来搭建动态网站或者服务器的开源软件,本身都是各自独立 的程序,但是因为常被放在一起使用,拥有了越来越高的 ...

  6. [资料分享]SQL Server 2016/2014/2012/2008简体中文企业版下载+对应补丁

    为什么只提供企业版下载呢?因为不管你是学生还是工作研究人员,企业版都是功能最为齐全的一个版本,比如企业版都集成了SQL Server Management Studio管理界面(俗称企业管理器的可视化 ...

  7. [资料分享]ACCESS2013 零基础到精通

    Microsoft Office Access是由微软发布的关系数据库管理系统.它结合了 MicrosoftJet Database Engine 和 图形用户界面两项特点,是 Microsoft O ...

  8. 在树霉派上配置LAMP

    apache2 配置文件: /etc/apache2/sites-enabled下的000-default.conf <VirtualHost *:> # The ServerName d ...

  9. python小程序

    使用python实现在crt中捕捉出现的异常信息,并统计出现的次数: #$language = "Python" #$interface = "1.0" def ...

  10. JavaScript 中string方法

    注意:JavaScript的字符串是不可变的(immutable),String类定义的方法不能改变原来字符串内容,例如String.toUpperCase()这样的方法,返回的是全新的字符串,而不是 ...