IOC 容器在 ASP.NET MVC 中的应用

IOC:Inversion Of Control 翻译为控制反转,我们在面向对象软件开发过程中,一个应用程序它的底层结构可能由N种不同的构件来相互协作来完成我们定义的系统的业务逻辑。哪么每一个构件可能相互独立和相互依赖,如果相互依赖的构件中的某一个构件出现异常,就会影响到整个系统的稳定运行,对象之间的耦合关系是无法避免的,也是必要的,因为这是协同工作的基础。如何降低系统之间、模块之间和对象之间的耦合度,是软件工程永远追求的目标之一。为了解决对象之间的耦合度过高的问题,IOC 的理念被提出,并被成功地应用到实践当中。说直白一点,就是对象之间的创建与维护我们全权交给了外部容器来管理,这样就实现了所谓的反转。

.NET 体系下这些相对成熟轻量级的IOC 容器,Castle Windsor、Unity、Spring.NET、StructureMap和Ninject等,下面我们就开始演示IOC在ASP.NET MVC 下的应用,在这里我们选择 Castle 来做为 IOC 容器。ASP.NET MVC 的 Controller 激活是靠ControllerFactory来创建的Controller对象的,所以我们就直接创建一个WindsorControllerFactory类,通过继承自DefaultControllerFactory来实现Controller的实例创建解析和释放等功能。

 1 using Castle.Core.Resource;
2 using Castle.Windsor;
3 using Castle.Windsor.Configuration.Interpreters;
4 using System;
5 using System.Linq;
6 using System.Reflection;
7 using System.Web.Mvc;
8
9 namespace mvc_with_Castle.App_Start
10 {
11 public class WindsorControllerFactory : DefaultControllerFactory
12 {
13 private WindsorContainer container;
14 public WindsorControllerFactory()
15 {
16 container = new WindsorContainer(
17 new XmlInterpreter(new ConfigResource("castle"))
18 );
19
20 var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
21 where typeof(IController).IsAssignableFrom(t)
22 select t;
23 foreach (Type t in controllerTypes)
24 container.AddComponentLifeStyle(t.FullName, t, Castle.Core.LifestyleType.Transient);
25 }
26
27 protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
28 {
29 return (IController)container.Resolve(controllerType);
30 }
31 }
32 }

一个自定义的WindsorControllerFactory就这么简单的创建完了,下一步创建一个基于 IWindsorInstaller 的对容器的安装类

using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using System.Web.Mvc; namespace mvc_with_Castle.App_Start
{
public class ControllersInstaller : IWindsorInstaller
{
public void Install(Castle.Windsor.IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly()
.BasedOn<IController>()
.LifestyleTransient().Configure(c => c.DependsOn()));
}
}
}

接下来我们对Global.asax做一些修改,注册我们默认的 WindsorControllerFactory 控制器工厂类。

 1 using Castle.Windsor;
2 using Castle.Windsor.Installer;
3 using mvc_with_Castle.App_Start;
4 using System.Web.Mvc;
5 using System.Web.Optimization;
6 using System.Web.Routing;
7
8 namespace mvc_with_Castle
9 {
10 public class MvcApplication : System.Web.HttpApplication
11 {
12 private static IWindsorContainer container;
13 private static void MyContainer()
14 {
15 container = new WindsorContainer().Install(FromAssembly.This());
16
17 var controllerFactory = new WindsorControllerFactory();
18 ControllerBuilder.Current.SetControllerFactory(controllerFactory);
19 }
20 protected void Application_Start()
21 {
22 AreaRegistration.RegisterAllAreas();
23 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
24 RouteConfig.RegisterRoutes(RouteTable.Routes);
25 BundleConfig.RegisterBundles(BundleTable.Bundles);
26
27 MyContainer();
28 }
29
30 protected void Application_End()
31 {
32 container.Dispose();
33 }
34 }
35 }

所有的准备工作差不多都准备完毕,接下来我们就来定义一个接口实现对人员的查询

 1 using System.Collections.Generic;
2
3 namespace mvc_with_Castle.Service
4 {
5 public class SysUser
6 {
7 public string Name { get; set; }
8
9 public string Sex { get; set; }
10
11 public string Phone { set; get; }
12
13 public string Address { get; set; }
14
15 public string Email { get; set; }
16 }
17
18 public interface IUsersSvr
19 {
20 IEnumerable<SysUser> QueryUsers();
21 }
22
23 public class UsersSvr : IUsersSvr
24 {
25 private static IList<SysUser> list;
26
27 static UsersSvr()
28 {
29 list = new List<SysUser>();
30 for (int i = 0; i < 10; i++)
31 {
32 list.Add(new SysUser()
33 {
34 Name = "如花" + i,
35 Sex = "男",
36 Phone = "13882880818",
37 Address = "皇后大道中段" + i + "号",
38 Email = "jack@gmail.com"
39 });
40 }
41 }
42
43 public IEnumerable<SysUser> QueryUsers()
44 {
45 return list;
46 }
47 }
48 }

再下来就是我们对Castle IOC的配置管理

 1  <configSections>
2 <section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor"/>
3 </configSections>
4
5 <!--注册服务-->
6 <castle>
7 <components>
8 <component id="UsersSvr" type="mvc_with_Castle.Service.UsersSvr, mvc_with_Castle" service="mvc_with_Castle.Service.IUsersSvr, mvc_with_Castle" lifestyle="Singleton"/>
9 </components>
10 </castle>

最后调用我们定义的 IUserSvr 接口来实现查询数据

 1 using System.Collections.Generic;
2 using System.Web.Mvc;
3 using mvc_with_Castle.Service;
4
5 namespace mvc_with_Castle.Controllers
6 {
7 public class HomeController : Controller
8 {
9 public IUsersSvr _svr { get; set; }
10 public ActionResult Index()
11 {
12 IEnumerable<SysUser> list = _svr.QueryUsers();
13 return View(list);
14 }
15 }
16 }

人员信息显示效果如下 

在这里我们已经大概了解了什么是IOC容器,和在 ASP.NET MVC 下面我们怎样利用 IOC 容器来实现通过接口的方式来进行服务的调用的大致原理,在上面的HomeController里面,很明显我们不用担心接口怎么被实例化的,或者说我们没明白服务到底怎么被激活了,哪么再回头看看前面的代码是不是就一目了然了呢 ?

 
 

IOC 容器在 ASP.NET MVC 中的应用的更多相关文章

  1. Unity容器在asp.net mvc中的IOC应用及AOP应用

    <asp.net-mvc框架揭秘>一书中,有个示例,是使用unity容器来注入自定义的控制器工厂.代码示例可以自己去下载源码,在这里我就不说了.IOC容器的本质是解耦的实例化接口类,而如何 ...

  2. ADO.NET .net core2.0添加json文件并转化成类注入控制器使用 简单了解 iTextSharp实现HTML to PDF ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下 C# AutoMapper 了解一下

    ADO.NET   一.ADO.NET概要 ADO.NET是.NET框架中的重要组件,主要用于完成C#应用程序访问数据库 二.ADO.NET的组成 ①System.Data  → DataTable, ...

  3. [转]ASP.NET MVC中你必须知道的13个扩展点

    本文转自:http://www.cnblogs.com/ejiyuan/archive/2010/03/09/1681442.html ScottGu在其最新的博文中推荐了Simone Chiaret ...

  4. Asp.net mvc 中Action 方法的执行(二)

    [toc] 前面介绍了 Action 执行过程中的几个基本的组件,这里介绍 Action 方法的参数绑定. 数据来源 为 Action 方法提供参数绑定的原始数据来源于当前的 Http 请求,可能包含 ...

  5. Asp.net mvc 中Action 方法的执行(一)

    [toc] 在 Aps.net mvc 应用中对请求的处理最终都是转换为对某个 Controller 中的某个 Action 方法的调用,因此,要对一个请求进行处理,第一步,需要根据请求解析出对应的 ...

  6. Asp.net mvc 中的 Controller 的激活

    Controller 激活是指根据路由系统解析出来的 Controller 的名称创建 控制器(Controller)的过程,这里的控制器泛指实现了 IController 接口的类型 激活过程中的核 ...

  7. Asp.net mvc 中View 的呈现(二)

    [toc] 上一节介绍了 Asp.net mvc 中除 ViewResult 外的所有的 ActionResult,这一节介绍 ViewResult. ViewResultBase ViewResul ...

  8. 在ASP.NET MVC中使用Castle Windsor

    平常用Inject比较多,今天接触到了Castle Windsor.本篇就来体验其在ASP.NET MVC中的应用过程. Visual Studio 2012创建一个ASP.NET MVC 4网站. ...

  9. ASP.NET MVC中你必须知道的13个扩展点

         ScottGu在其最新的博文中推荐了Simone Chiaretta的文章13 ASP.NET MVC extensibility points you have to know,该文章为我 ...

随机推荐

  1. jquery初步总结

    1.$(document).ready()方法和window.onload差分法 为页元件的正确操作,我们需要把操作元件JS编写的代码$(document).ready()(Jquery)或windo ...

  2. 新安装Win10

    随着微软发布Windows 10下载技术预览版.现在,您可以免费下载Windows 10技术预览ISO档,安装和开放经验. Windows 10技术预览提供的第一部英语.中国简体.葡萄牙语,含32位. ...

  3. Net 一个请求的处理流程

    Net 一个请求的处理流程   1.浏览器请求 请求-准备环境-->处理请求   2.Aspnet 环境的创建 客户请求 IIS区分静态文件还是动态文件,静态文件直接文件返回,动态文件通过asp ...

  4. ES6 扫盲

    原文地址:ECMAScript 6 扫盲--小胡子 1. let.const 和 block 作用域 let 允许创建块级作用域,ES6 推荐在函数中使用 let 定义变量,而非 var: var a ...

  5. XStream 用法汇总

            XStream是一家Java对象和XML转换工具,很好很强大.它提供了所有的基本型.排列.收集和其他类型的支持,直接转换.因此XML在数据交换经常使用.对象序列化(和Java对象的序列 ...

  6. QtQuick桌面应用程序开发指导 3)达到UI而功能_B 4)动态管理Note物_A

    3.2 把Page Item和Marker Item绑定 之前我们实现了PagePanel组件, 使用了三个state来切换Page组件的opacity属性; 这一步我们会使用Marker和Marke ...

  7. 平原绫香 Hirahara Ayaka-Jupiter

    我第一次听到平原绫香(Hirahara Ayaka)久石让在武道馆演唱会.她的歌声真的很震惊! 声音是如此的纯净,演唱会是如此的优雅.她着迷,只是如此美丽. 然后我去检查她的信息.发现Jupiter. ...

  8. 大数据系列修炼-Scala课程07

    由于昨天下班后有点困,就没有来及写博客,今天会把它补上!把这个习惯坚持下去! 关于Scala高阶函数详解 1.Scala高阶函数代码实现:高阶函数就是在我们函数中套用函数 2.高阶函数代码详解:高阶函 ...

  9. 使用JS的FormData对象

    利用FormData对象,你可以使用一系列的键值对来模拟一个完整的表单,然后使用XMLHttpRequest发送这个"表单". 创建一个FormData对象 你可以先创建一个空的F ...

  10. Skype发布视频API

    原文:Skype发布视频API 相信很多人对Skype多少都应该有一些了解,如果以前没有使用过它的服务的话,也应该在最近的新闻中听说过它的大名.因为,它和我们每天都在接触的公司--Mircrosoft ...