zoukankan      html  css  js  c++  java
  • 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里面,很明显我们不用担心接口怎么被实例化的,或者说我们没明白服务到底怎么被激活了,哪么再回头看看前面的代码是不是就一目了然了呢 ?

        

  • 相关阅读:
    mysqlnd cannot connect to MySQL 4.1+ using old authentication
    nginx中查看关于php的配置和php-fpm的重启等操作
    nginx中查看关于php的配置和php-fpm的重启等操作
    linux面试题1
    linux笔试
    面试题
    shell脚本实例
    shell脚本
    mysql主从复制
    Discuz!NT静态文件缓存(SQUID)
  • 原文地址:https://www.cnblogs.com/xiangziyanhuang/p/3740225.html
Copyright © 2011-2022 走看看