平常用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. House Robber I & II & III

    House Robber You are a professional robber planning to rob houses along a street. Each house has a c ...

  2. nginx + php + centos 6.3

    2014年2月7日 22:34:52 PHP 5.5.9 http://cn2.php.net/distributions/php-5.5.9.tar.bz2 nginx 1.5.10 http:// ...

  3. pandas删除dataframe列

    data2 = data.drop(data.columns[0,1,3,4,6,8,10], 1)

  4. KNN算法的感受 1

    本来预计的打算是一天一个十大挖掘算法,然而由于同时要兼顾数据结构面试的事情,所以 很难办到,但至少在回家前要把数据挖掘十大算法看完,过个好年,在course上学习老吴的课程还是帮了我很大的忙,虽然浪费 ...

  5. Ubuntu下pycharm安装

    参考:http://blog.csdn.net/langb2014/article/details/51166782 http://www.cnblogs.com/zhcncn/p/4027025.h ...

  6. MyISAM引擎和InnoDB引擎的特点

    随着MySQL的不断更新,由于各存储引擎功能特性差异较大,这篇文章主要是介绍如何来选择合适的存储引擎来应对不同的业务场景,朋友们可以根据业务需求,选择合适的存储引擎.^.^ MyISAM 特性 不支持 ...

  7. Oracle学习笔记:使用replace、regexp_replace实现字符替换、姓名脱敏

    在数据库中难免会遇到需要对数据进行脱敏的操作,无论是姓名,还是身份证号. 最近遇到一个需求,需要对姓名进行脱敏: 姓名长度为2,替换为姓+*: 姓名长度为3,替换中间字符为*: 姓名长度为4,替换第3 ...

  8. Java编程的逻辑 (58) - 文本文件和字符流

    本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...

  9. docker:定制node.js的版本

    本想用alpine,但如果想使用node.js 6.3.1版本的软件, 总会搞不定glibc和libstdc++报一个无法识别版本信息的错误. 搞了一天,算了.使用debian:stretch-sli ...

  10. StringUtils一些常用方法

    StringUtils是org.apache.commons.lang jar包里面的类方法,当输入参数String为null则不会抛出NullPointerException,而是做了相应处理,nu ...