ASP.NET MVC 控制器激活(二)

简介:

ASP.NET MVC 控制器激活(二)

前言

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

 

激活控制器-注入点入口

如上图,这是上个篇幅中描述的控制器激活过程图,这里引用过来是怕有的朋友忘记了前面的所说和没看过前面篇幅的朋友。

 

就从默认控制器工厂的实现来看,在CreateController()方法中,通过GetControllerType()方法来获取控制器类型(Type),然后传递到GetControllerInstance()方法中,通过其中的实现来完成根据控制器类型(Type)到IController的生成。而在后续的注入点也是在GetControllerInstance()方法实现中来进行注入的,GetControllerInstance()方法即是整个控制器激活过程的入口点。

IoC示例

既然说到了动态注入,想必就要用到IoC框架了,在MVC学前篇中提到过Ninject的使用,下面这个示例便是依赖于Ninject的来做的演示:

1
2
3
4
5
6
7
8
1      /// <summary>
2      /// 产品实体类
3      /// </summary>
4      public  class  Product
5     {
6          public  string  ID {  get set ; }
7          public  string  Name {  get set ; }
8     }

定义一个数据实体类没什么好说的,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
  1      /// <summary>
  2      /// 抽象数据提取库
  3      /// </summary>
  4      public  interface  IDataStandard
  5     {
  6         List<Product> GetProducts();
  7     }
  8      /// <summary>
  9      /// 默认实现--数据提取库
10      /// </summary>
11      public  class  DataProvide : IDataStandard
12     {
13 
14          public  List<Product> GetProducts()
15         {
16             List<Product> products =  new  List<Product>() 
17             {
18                  new  Product(){ ID= "1" ,Name= "name1" },
19                  new  Product(){ID= "2" ,Name= "name2" },
20                  new  Product(){ID= "3" ,Name= "name3" }
21             };
22              return  products;
23         }
24     }

这里定义的一个是抽象的数据提取库,和一个默认的实现作为演示用于提供数据用的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  1      /// <summary>
  2      /// 抽象数据调用
  3      /// </summary>
  4      public  interface  IDataCall
  5     {
  6          void  WriterToMonitor();
  7     }
 
  9      /// <summary>
10      /// 默认的数据调用实现
11      /// </summary>
12      public  class  DefultDataCall:IDataCall
13     {
14          private  IDataStandard _DataStandard;
15 
16          public  DefultDataCall(IDataStandard dataStandard) //使用构造函数方式注入 通过Ninject框架实现
17         {
18             _DataStandard = dataStandard;
19         }
20 
21          public  void  WriterToMonitor()
22         {
23              foreach ( var  data  in  _DataStandard.GetProducts())
24             {
25                 Console.WriteLine( "Prodcut ID:"  + data.ID +  " Name:"  + data.Name);
26             }
27         }
28     }

这里定义的是抽象的数据调用和默认的实现,我们现在要做的就是通过IoC框架来让调用客户端对数据调用和数据提取解耦,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  class  Program
  2     {
  3          static  void  Main( string [] args)
  4         {
  5             IKernel ninject =  new  StandardKernel();
  6             ninject.Bind<IDataStandard>().To<DataProvide>();
  7             IDataCall dataCall = ninject.Get( typeof (DefultDataCall))  as  IDataCall;
  8              if  (dataCall !=  null )
  9             {
10                 dataCall.WriterToMonitor();
11             }
12 
13             Console.ReadLine();
14         }
15     }

运行这段代码:

很简单明了的一个示例,在MVC的项目中也是这样运行的。

 

MVC项目中的运用

在上面的章节里说过,入口点在protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType);方法中,我们只需要实现一个默认的控制器工厂类型,并且重写一下这个方法,因为我们已经可以在重写的方法中获取到控制器的类型了,有了它就可以按照IoC示例中的那样来进行其它对象到控制器的一个动态注入。

我们先要定义一个控制器,并且要让它对上述示例中的抽象提取库依赖,采取构造函数式注入(依赖)。

看一下示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  1      public  class  IoCDemoController : Controller
  2     {
  3          //
  4          // GET: /IoCDemo/
 
  6          private  IDataStandard _DataStandard;
 
  8          public  IoCDemoController(IDataStandard dataStandard)
  9         {
10             _DataStandard = dataStandard;
11         }
12 
13          public  ActionResult Index()
14         {
15              return  View(_DataStandard.GetProducts());
16         }
17     }

在Index方法上右键,点击添加视图:

点击添加,并且在视图中输入如下代码:

1
2
3
4
5
6
7
8
9
@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文件中的路由设置修改一下:

1
2
3
4
5
1 routes.MapRoute(
2                  "Default" // 路由名称
3                  "{controller}/{action}/{id}" // 带有参数的 URL
4                  new  { controller =  "IoCDemo" , action =  "Index" , id = UrlParameter.Optional }  // 参数默认值
5             );

这个时候准备工作都做好,可是控制器中所用的数据哪里来呢?从我们默认实现的控制器工厂中来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
   1      public  class  NinjectControllerFactory :DefaultControllerFactory
  2     {
  3          private  IKernel _NinjectKernel;
 
  5          public  NinjectControllerFactory()
  6         {
  7             _NinjectKernel =  new  StandardKernel();
  8             _NinjectKernel.Bind<IDataStandard>().To<DataProvide>();
  9         }
10 
11          protected  override  IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
12         {
13             IController controller = _NinjectKernel.Get(controllerType)  as  IController;
14              if  (controller !=  null
15             {
16                  return  controller;
17             }
18              return  null ;
19         }
20 
21     }

按照上面章节中的样式,在NinjectControllerFactory中事先绑定数据类型,等到系统执行需要用到控制器的时候会通过Ninject框架来讲数据动态的注入到控制器中。

最后还要设置一项:

在Global.asax文件中的Application_Start()方法中要把我们默认的实现的控制器工厂设置到MVC框架中,

1
2
3
4
5
6
7
8
protected  void  Application_Start()
2         {
3             AreaRegistration.RegisterAllAreas();
5             RegisterGlobalFilters(GlobalFilters.Filters);
6             RegisterRoutes(RouteTable.Routes);
7             ControllerBuilder.Current.SetControllerFactory( new  NinjectControllerFactory());
8         }

添加上代码的最后一句。现在我们就可以来看一下最终效果了。

本篇就讲到这里,会在下个篇幅中继续讲解其他的注入点。

 

 









     本文转自jinyuan0829 51CTO博客,原文链接:http://blog.51cto.com/jinyuan/1425165,如需转载请自行联系原作者



相关文章
|
监控 前端开发 API
一款基于 .NET MVC 框架开发、功能全面的MES系统
一款基于 .NET MVC 框架开发、功能全面的MES系统
612 5
|
前端开发 Java 开发者
Spring MVC中的控制器:@Controller注解全解析
在Spring MVC框架中,`@Controller`注解是构建Web应用程序控制层的核心。它不仅简化了控制器的定义,还提供了灵活的请求映射和处理机制。本文将深入探讨`@Controller`注解的用法、特点以及在实际开发中的应用。
1208 0
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
356 7
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
347 0
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
298 0
|
开发框架 前端开发 安全
ASP.NET MVC 如何使用 Form Authentication?
ASP.NET MVC 如何使用 Form Authentication?
471 0
|
开发框架 .NET
Asp.Net Core 使用X.PagedList.Mvc.Core分页 & 搜索
Asp.Net Core 使用X.PagedList.Mvc.Core分页 & 搜索
711 0
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
701 0
|
存储 开发框架 前端开发
[回馈]ASP.NET Core MVC开发实战之商城系统(五)
经过一段时间的准备,新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始,在之前的文章中,讲解了商城系统的整体功能设计,页面布局设计,环境搭建,系统配置,及首页【商品类型,banner条,友情链接,降价促销,新品爆款】,商品列表页面,商品详情等功能的开发,今天继续讲解购物车功能开发,仅供学习分享使用,如有不足之处,还请指正。
430 0
|
开发框架 前端开发 .NET
[回馈]ASP.NET Core MVC开发实战之商城系统(三)
[回馈]ASP.NET Core MVC开发实战之商城系统(三)
333 0