Castle最早在2003年诞生于Apache Avalon项目,目的是为了创建一个IOC(控制反转)框架。发展到现在已经有四个组件了,分别是ActiveRecord(ORM组件),Windsor(IOC组件),DynamicProxy(动态代理组件),MonoRail(Web MVC组件)。

>> IOC-Castle Windor学习

一直想研究公司架构,不知从何下手,那就从Global开始吧,首先讲到的是Castle 注入,我在Word里面总结了下,就直接Copy过来了,代码测试正常,有看不懂的欢迎提问~

1.首先在Global里面进行注册:

 private IWindsorContainer _container;

//初始化一个IOC容器

  _container= new WindsorContainer().Install(FromAssembly.This());

//完成IWindsorInstaller接口中的注册

ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(_container.Kernel));

2.需要自定义一个实例:

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

using Castle.MicroKernel;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using System.Web.Routing;

namespace Demo

{

    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(, string.Format("当前对{0}的请求不存在", requestContext.HttpContext.Request.Path));

            }

            return (IController)_kernel.Resolve(controllerType);

        }

        public override void ReleaseController(IController controller)

        {

            _kernel.ReleaseComponent(controller);

            base.ReleaseController(controller);

        }

    }

}

3.声明一个类,定义依赖关系

public class TargetInstall : IWindsorInstaller

 {

 public void Install(IWindsorContainer container, 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实例

  container.Register(Classes.FromThisAssembly()

                .Where(t=>t.Name.EndsWith("son"))

                .WithServiceDefaultInterfaces()

                .Configure(c=>c.LifestyleTransient())

                );

 }

 }

上面这个定义的依赖关系仅仅指定了以son结尾的Person类,如果在定义一个其他的不是以son结尾的类,那么就无法实现映射了,有局限性。 接下来修改为另一种方法做映射,这样只要按照指定规则在接口上面做标记就可以实现动态映射了。代码如下:

下面这段代码可以替换掉类TargetInstall 里面的以son结尾做映射的那段代码了:

var componentList = new List<IRegistration>();

            var classes = Assembly.GetExecutingAssembly().GetTypes().Where(p => p.IsVisible).Where(p => ((ServiceAttribute)p.GetCustomAttributes(typeof(ServiceAttribute), false).FirstOrDefault()) != null).ToList();

            foreach (var item in classes)

            {

                var name = item.FullName;

                var baseType = ((ServiceAttribute)item.GetCustomAttributes(typeof(ServiceAttribute), false).First()).BaseType;

                componentList.Add(Component.For(baseType).ImplementedBy(item).Named(name));

            }

            container.Register(componentList.ToArray());

上面那段代码涉及到一个自定义类ServiceAttribute (这个类就是自定义一个属性)

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

namespace Demo

{

    public class ServiceAttribute:Attribute

    {

        /// <summary>

        /// 设置或取得基类

        /// </summary>

        public Type BaseType { get; set; }

    }

}

最后在想要实现映射的类里面加标记就行了,比如Person类:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

namespace Demo

{

    [Service(BaseType =typeof(IPerson))]

    public class Person : IPerson

    {

        public string Speak(string name)

        {

            return name;

        }

    }

}

上面是使用代码直接注入,还可以通过配置文件注入,如下:

1.在Global里面进行注册:

 //Castle配置文件注入
_container = new WindsorContainer(ConfigurationManager.AppSettings["IWindsorContainer"]);
_container.Install(FromAssembly.This());
ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(_container.Kernel));//设置自定义控制工厂

2.进行Web配置:

 <add key="IWindsorContainer" value="config\castle.xml" />

根据配置编写如下文件:

>>Castle.xml

<?xml version="1.0" encoding="utf-8" ?>
<castle>
<include uri="file://castle/components.config" />
</castle>

>>Components.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<components>
<!--这里就写对应的接口和类,注意id别重复就行了-->
<component id="GoldCRM.Domain.HXDataImport"
service="Demo.IPerson,Demo"
type="Demo.Person,Demo" >
</component>
</components>
</configuration>

3.定义依赖关系:

public class ControllersInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
//实现IController接口
container.Register(Classes.FromThisAssembly()
.BasedOn<IController>()
.LifestyleTransient());
}
}   

4.需要自定义一个实例重写DefaultContgrollerFactory,参考上面即可:

--记得使用配置文件进行注册,每新增一个接口,要记得手动添加到配置文件哦~ 访问时就构造函数访问即可:

private IPerson person;

public HomeController(IPerson person)

{

this.person=person;

}  

好了,Castle注入讲完了~

>>上面主要讲了Castle注入,既然说到这了,就接着上面把【拦截器】讲了吧:

拦截器可以在一个方法执行之前执行某些操作,并可以阻断方法的执行。

1.首先定义一个拦截器类:

 public class ServiceInterceptor : IInterceptor
{
/// <summary>
/// 拦截方法
/// </summary>
/// <param name="invocation"></param>
public void Intercept(IInvocation invocation)
{ invocation.Proceed();
}
}

2.其次在继承IWindsorInstaller的类里面进行注册:,我就在TargetInstall里面直接写了(PS:按道理为了清晰,分工明确是应该单独建立一个类写的):

 public class TargetInstall : IWindsorInstaller
{ private const string Interceptors = "Demo2.ServiceInterceptor";
public void Install(IWindsorContainer container, IConfigurationStore store)
{
//实现IController接口
container.Register(Classes.FromThisAssembly()
.BasedOn<IController>()
.LifestyleTransient()); //注册拦截器
container.Register(Classes.FromThisAssembly()
.BasedOn<IInterceptor>());
//注册Service方法
var componentList = new List<IRegistration>();
var classes = Assembly.GetExecutingAssembly().GetTypes().Where(p => p.IsVisible).Where(p => ((ServiceAttribute)p.GetCustomAttributes(typeof(ServiceAttribute), false).FirstOrDefault()) != null).ToList(); foreach (var item in classes) {
var name = item.FullName;
var baseType = ((ServiceAttribute)item.GetCustomAttributes(typeof(ServiceAttribute), false).First()).BaseType; componentList.Add(Component.For(baseType).ImplementedBy(item).Named(name).Interceptors(Interceptors));
//Interceptors(Interceptors)这段是将拦截器注入
} container.Register(componentList.ToArray());
}
}

Action拦截器参考:http://blog.csdn.net/gulijiang2008/article/details/7427223  

好啦,拦截器就这么多啦,你运行的话,会发现先走拦截器再走方法哒~

接下来讲NHibernate学习→_→

IOC-Castle Windsor映射的更多相关文章

  1. IoC - Castle Windsor 2.1

    找过一些Windsor教程的文章,博客园上TerryLee有写了不少,以及codeproject等也有一些例子,但都讲的不太明了.今天看到Alex Henderson写的一个系列,非常简单明了.下面是 ...

  2. 小白初学Ioc、DI、Castle Windsor依赖注入,大神勿入(不适)

    过了几天,我又来了.上一篇中有博友提到要分享下属于我们abp初学者的历程,今天抽出点时间写写吧.起初,我是直接去看阳光铭睿的博客,看了一遍下来,感觉好多东西没接触过,接着我又去下了github 里面下 ...

  3. 多个IoC容器适配器设计及性能测试(Castle.Windsor Autofac Spring.Core)

    [转]多个IoC容器适配器设计及性能测试和容器选择 1. 采用的IoC容器和版本 Autofac.2.6.3.862 Castle.Windsor.3.1.0 Spring.Core.2.0.0 2. ...

  4. Castle.Windsor IOC/AOP的使用

    Castle最早在2003年诞生于Apache Avalon项目,目的是为了创建一个IOC(控制反转)框架.发展到现在已经有4个组件了,分别是ActiveRecord(ORM组件).Windsor(I ...

  5. Castle Windsor Ioc 一个接口多个实现解决方案

    介绍 Castle Windsor 是微软的Ioc类库,本文主要介绍解决一个接口多个实现的解决方案 接口和类 以下内容不是真实的实际场景,仅仅是提供解决一个接口多个实现的思路. 业务场景类 先假设有一 ...

  6. 避免Castle Windsor引起的内存泄露

    原文地址: http://nexussharp.wordpress.com/2012/04/21/castle-windsor-avoid-memory-leaks-by-learning-the-u ...

  7. Castle Windsor常用介绍以及其在ABP项目的应用介绍

    最近在研究ABP项目,有关ABP的介绍请看阳光铭睿 博客,ABP的DI和AOP框架用的是Castle Windsor下面就对Castle Windsor项目常用方法介绍和关于ABP的使用总结 1.下载 ...

  8. Aspect Oriented Programming using Interceptors within Castle Windsor and ABP Framework AOP

    http://www.codeproject.com/Articles/1080517/Aspect-Oriented-Programming-using-Interceptors-wit Downl ...

  9. 说说ABP项目中的AutoMapper,Castle Windsor(痛并快乐着)

    这篇博客要说的东西跟ABP,AutoMapper和Castle Windsor都有关系,而且也是我在项目中遇到的问题,最终解决了,现在的感受就是“痛并快乐着”. 首先,这篇博客不是讲什么新的知识点,而 ...

随机推荐

  1. 对比JavaScript的入口函数和jQuery的入口函数

    JavaScript的入口函数要等到页面中所有的资源(包括图片.文件)加载完成才开始执行. jQuery的入口函数只会等待文档数加载完成就开始执行,并不会等待图片.文件的加载.

  2. (转载) android studio library生成jar包和aar的方法总结

    android studio library生成jar包和aar的方法总结 标签: android学习文档jar和aar的使用与生成gradle 2016-11-25 10:39 1782人阅读 评论 ...

  3. Android学习——利用RecyclerView编写聊天界面

    1.待会儿会用到RecyclerView,首先在app/build.gradle(注意有两个build.gradle,选择app下的那个)当中添加依赖库,如下: dependencies { comp ...

  4. RFID 知识的学习

    * 部分资料来自我们博士的PPT,部分来自网络和他人的论文. * 我们使用的教材是清华大学出版社出版的<智能卡技术(第四版)——IC卡.RFID标签与物联网(清华大学计算机系列教材)>(王 ...

  5. 完整安装sqlserver always on集群

    准备工作 1.  四台已安装windows server 2008 r2 系统的虚拟机,配置如下: CPU : 1核 MEMORY : 2GB DISK : 40GB(未分区) NetAdapter ...

  6. 优动漫PAINT之绘画助手软件简介

    在下载安装优动漫PAINT的时候,它会附带一个叫做绘画助手的一个小软件.绘画助手是一款用于PC端的创作辅助工具软件,针对画师们在绘画时可能遇到的各种问 题和需求,提供了作品保护.云配置.软件管理.色板 ...

  7. php 的多进程

    php的多进程处理依赖于pcntl扩展,通过pcntl_fork创建子进程来进行并行处理 例子1: <?php $pid = pcntl_fork(); if($pid == -1) { //错 ...

  8. a标记地址的几种用法

    1.<a href="tel://号码"></a> 手机使用能自动拨打电话 //可以省略 2.<a href="mailto://邮箱&qu ...

  9. kernel对NTP的API,系统调用函数

    kenrel API for NTP kernel 提供两个API(即系统调用 system call)给应用程序NTP,去校准kernel system clock Kernel Applicati ...

  10. hibernate在maven中自动生成

    1.构建数据库连接 2.新建maven项目,利用工具生成hibernate相应的类和xml文件 新建pojo包 右击项目 点击Configure Facets 选择hibernate 选择包 选择驱动 ...