平常用Inject比较多,今天接触到了Castle Windsor。本篇就来体验其在ASP.NET MVC中的应用过程。

Visual Studio 2012创建一个ASP.NET MVC 4网站。

通过NuGet安装Castle Windsor。

在当前项目下创建一个名称为"IOC"的文件夹。

在ASP.NET MVC中,每次请求,DefaultControllerFactory都会为我们创建controller实例,我们需要自定义一个派生自DefaultControllerFactory的类,让Castle Windsor帮我们生成controller实例。

using System.Web;
using System.Web.Mvc;
using Castle.MicroKernel;

namespace MyCastleWindsor.IOC
{
    public class WindsorControllerFactory : DefaultControllerFactory
    {
        private readonly IKernel _kernel;

        public WindsorControllerFactory(IKernel kernel)
        {
            _kernel = kernel;
        }

        protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, System.Type controllerType)
        {
            if (controllerType == null)
            {
                throw  new HttpException(404,string.Format("当前对{0}的请求不存在",requestContext.HttpContext.Request.Path));
            }
            return (IController)_kernel.Resolve(controllerType);
        }

        public override void ReleaseController(IController controller)
        {
            _kernel.ReleaseComponent(controller);
            base.ReleaseController(controller);
        }
    }
}


现在需要在全局中生成Castle Windsor实例,赋值给自定义ControllerFactory的构造函数,并在Application结束时销毁该Castle Windsor实例。

   public class MvcApplication : System.Web.HttpApplication
    {
        private IWindsorContainer _container;

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            //初始化一个IOC容器
            _container = new WindsorContainer().Install(FromAssembly.This());

            //完成IWindsorInstaller接口中的注册
            ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(_container.Kernel));
        }

        protected void Application_End()
        {
            _container.Dispose();
        }
    }


现在,需要告诉Castle Windsor在何种条件下,以怎样的方式注册依赖。Castle Windsor提供了IWindsorInstaller接口。在IOC文件夹下创建实现该接口的类。

using System.Web.Mvc;
using Castle.MicroKernel.Registration;
using MyCastleWindsor.Controllers;

namespace MyCastleWindsor.IOC
{
    public class ControllerInstaller : IWindsorInstaller
    {

        public void Install(Castle.Windsor.IWindsorContainer container, Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store)
        {
            container.Register(Classes.FromThisAssembly() //在哪里找寻接口或类
                .BasedOn<IController>() //实现IController接口
                .If(Component.IsInSameNamespaceAs<HomeController>()) //与HomeController在同一个命名空间
                .If(t => t.Name.EndsWith("Controller")) //以"Controller"结尾
                .Configure(c => c.LifestylePerWebRequest()));//每次请求创建一个Controller实例
        }
    }
}

而实际上,在全局文件中,当运行Install(FromAssembly.This())方法时,会执行 IWindsorInstaller的Install接口方法。

举例来说

假设有一个接口:

public interface IContactManager
{}

接口的实现类:

public class ContactManager : IContactManager
{}

在某个控制器中,通过构造函数注入依赖,我们希望这样写:

private IContactManager contactManager;

public HomeController(IContactManager contactManager)
{
    this.contactManager = contactManager;
}

现在需要注册IContactManager和ContactManager。可以通过反射方式注册依赖。

using System.Web.Mvc;
using Castle.MicroKernel.Registration;
using MyCastleWindsor.Controllers;

namespace MyCastleWindsor.IOC
{
    public class ControllerInstaller : IWindsorInstaller
    {

        public void Install(Castle.Windsor.IWindsorContainer container, Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store)
        {

            container.Register(Classes.FromThisAssembly()
                .Where(t => t.Name.EndsWith("Manager"))
                .WithServiceDefaultInterfaces()
                .Configure(c => c.LifestyleTransient()));
        }
    }
}


关于Castle Windsor的应用大致如下:

→ 继承ASP.NET MVC的ControllerFactory,通过构造函数传入Castle Windsor的IKernel,让其解析出IController类型控制器。

→ 通过实现Castle Windsor的IWindsorInstaller接口,通过反射注册依赖关系。

→ 在全局文件中初始化Castle Windsor的实例,并注册自定义的ControllerFactory。

在ASP.NET MVC中使用Castle Windsor的更多相关文章

  1. MVC中使用Castle.Windsor

    我在MVC中使用Castle.Windsor是这样用的. 首先在UI层安装Install Castle.Windsor 在App_Start中增加一个类WindsorActivator,用于注册和销毁 ...

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

    IOC 容器在 ASP.NET MVC 中的应用 IOC:Inversion Of Control 翻译为控制反转,我们在面向对象软件开发过程中,一个应用程序它的底层结构可能由N种不同的构件来相互协作 ...

  3. 2.ASP.NET MVC 中使用Crystal Report水晶报表

    上一篇,介绍了怎么导出Excel文件,这篇文章介绍在ASP.NET MVC中使用水晶报表. 项目源码下载:https://github.com/caofangsheng93/CrystalReport ...

  4. 关于 ASP.NET MVC 中的视图生成

    在 ASP.NET MVC 中,我们将前端的呈现划分为三个独立的部分来实现,Controller 用来控制用户的操作,View 用来控制呈现的内容,Model 用来表示处理的数据. 从控制器到视图 通 ...

  5. 在Asp.Net MVC 中配置 Serilog

    Serilog 是一种非常简便记录log 的处理方式,使用Serilog可以生成本地的text文件, 也可以通过 Seq 来在Web界面中查看具体的log内容. 接下来就简单的介绍一下在Asp.Net ...

  6. 如何在 ASP.NET MVC 中集成 AngularJS(3)

    今天来为大家介绍如何在 ASP.NET MVC 中集成 AngularJS 的最后一部分内容. 调试路由表 - HTML 缓存清除 就在我以为示例应用程序完成之后,我意识到,我必须提供两个版本的路由表 ...

  7. 如何在 ASP.NET MVC 中集成 AngularJS(2)

    在如何在 ASP.NET MVC 中集成 AngularJS(1)中,我们介绍了 ASP.NET MVC 捆绑和压缩.应用程序版本自动刷新和工程构建等内容. 下面介绍如何在 ASP.NET MVC 中 ...

  8. 《Entity Framework 6 Recipes》中文翻译系列 (20) -----第四章 ASP.NET MVC中使用实体框架之在MVC中构建一个CRUD示例

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第四章  ASP.NET MVC中使用实体框架 ASP.NET是一个免费的Web框架 ...

  9. asp.net mvc 中 一种简单的 URL 重写

    asp.net mvc 中 一种简单的 URL 重写 Intro 在项目中想增加一个公告的功能,但是又不想直接用默认带的那种路由,感觉好low逼,想弄成那种伪静态化的路由 (别问我为什么不直接静态化, ...

随机推荐

  1. python3之模板pycurl探测web服务质量

    1.pycurl简介 pycURL是libcurl多协议文件传输库的python接口,与urllib模块类似,PycURL可用于从python程序中获取由URL标识的对象,功能很强大,libcurl速 ...

  2. arm交叉编译器gnueabi、none-eabi、arm-eabi、gnueabihf等的区别【转】

    转自:https://www.cnblogs.com/deng-tao/p/6432578.html 博客来之于:  http://www.veryarm.com/296.html 交叉编译工具链的命 ...

  3. Unity 网格 绘制

    网格绘制主要用是对Mesh进行操作,通过对vertex和triangles进行操作生成对应的面片: 这里首先得用到一个类:Triangulator(根据vertex生成triangles数组) usi ...

  4. 011_自定义mac通知的时长

    打开终端(找不到的点击 Mac 屏幕右上角放大镜按钮,Spotlight 搜索 “终端”),粘入下面这行命令,回车就行了.注意最后的 # 替换成你希望通知中心横幅停留的秒数,比如 15.default ...

  5. How to fix Eclipse Tomcat startup timeout in 45 seconds?

    命题:怎么修复 Eclipse 里启动 Tomcat 时, 默认启动超时时间为 45 秒的问题? 在 Eclipse 的 J2EE 项目里启动 Tomcat 来调试 Servlet 之类的,断点以后, ...

  6. Java环境的搭建及用记事本来揭露下JDK到底做了些什么

    和我一样的新手想学Java就从自己搭建环境开始,请看完这边文章,我搜集资料的整合. Java的标准版本是Java SE,所说的JDK(Java Development Kits)就是Java SE的开 ...

  7. 浅谈TCP拥塞控制算法

    TCP通过维护一个拥塞窗口来进行拥塞控制,拥塞控制的原则是,只要网络中没有出现拥塞,拥塞窗口的值就可以再增大一些,以便把更多的数据包发送出去,但只要网络出现拥塞,拥塞窗口的值就应该减小一些,以减少注入 ...

  8. nginx 日志切割(也适用于docker)

    =============================================== 2019/4/6_第2次修改                       ccb_warlock 201 ...

  9. spring动态加载(刷新)配置文件 [复制链接]

    待验证 在程序开发时,通常会经常修改spring的配置文件,不得不重启tomcat来加载spring配,费时费力.如果能在不重启tomcat的情况下,手动动态加载spring 配置文件,动态重启读取s ...

  10. 【前端node开发】你需要的Express开发教程

    1.极简Node教程-七天从小白变大神(一:你需要Express) https://www.jianshu.com/p/b4701a6efc50