思路话语

。Arlen:思想有多远你就能走多远...

Castle的IoC容器深入分析

 

本文引自:http://bokegu.com/forums/1536/ShowPost.aspx

大家都知道,Castle的Windsor容器非常强大,可以横向扩展的先进架构和自持自动连接等高级功能,并且充分利用了.Net的优势和特点,非常值得学习研究。
在Castle中添加和使用组件非常简单:
1IWindsorContainer container = new WindsorContainer( new XmlInterpreter("../BasicUsage.xml") );
2
3container.AddComponent( "newsletter"
4    typeof(INewsletterService), typeof(SimpleNewsletterService) );
5container.AddComponent( "smtpemailsender"
6    typeof(IEmailSender), typeof(SmtpEmailSender) );
7container.AddComponent( "templateengine"
8    typeof(ITemplateEngine), typeof(NVelocityTemplateEngine) );
9
这样就可以了,不需要像Spring.Net那样写连接配置文件,因为在Castle中组件之间的依赖关系是自动检测并连接的。
那么,Castle是如何做到的呢?
当AddComponent的时候,Windsor其实是调用了MicroKernel来进行注册,Windsor只是MicroKernel的一个包装,容器的主要功能其实都是MicroKernel完成的,而MicroKernel被设计成一个非常精巧,但是可扩展能力超强的一个内核结构。
在MicroKernel中,添加一个组件的具体的代码如下:
public virtual void AddComponent(String key, Type serviceType, Type classType)
{
    
if (key == nullthrow new ArgumentNullException("key");
    
if (serviceType == nullthrow new ArgumentNullException("serviceType");
    
if (classType == nullthrow new ArgumentNullException("classType");

    ComponentModel model 
= ComponentModelBuilder.BuildModel(key, serviceType, classType, null);
    RaiseComponentModelCreated(model);
    IHandler handler 
= HandlerFactory.Create(model);
    RegisterHandler(key, handler);
}

首先,ComponentModelBuilder给组件生成了一个ComponentModel,这个Model实际上是用大量的反射来捕获这个组件的各种详细的元信息,就好象先给你来一次X光扫描,这个组件是什么东西清清楚楚。
建立模型的具体过程如下:

public ComponentModel BuildModel(String key, Type service, Type classType, IDictionary extendedProperties)
{
    ComponentModel model 
= new ComponentModel(key, service, classType);
    
    
if (extendedProperties != null)
    {
        model.ExtendedProperties 
= extendedProperties;
    }

    
foreach(IContributeComponentModelConstruction contributor in contributors)
    {
        contributor.ProcessModel( kernel, model );
    }
    
    
return model;
}

其实具体过程就是调用contributor来进行具体的信息收集,每个Contributor负责收集不同的信息,在DefaultMicroKernel中一共注册了以下7个Contributor来收集信息:

protected virtual void InitializeContributors()
{
    AddContributor( 
new ConfigurationModelInspector() );
    AddContributor( 
new LifestyleModelInspector() );
    AddContributor( 
new ConstructorDependenciesModelInspector() );
    AddContributor( 
new PropertiesDependenciesModelInspector() );
    AddContributor( 
new LifecycleModelInspector() );
    AddContributor( 
new ConfigurationParametersInspector() );
    AddContributor( 
new InterceptorInspector() );
}

他们各有各的功能,你可以可以自己写Contributor来收集你想要收集的信息。
接下来就是发出ComponentCreated的事件,这个事件是一个容器的扩展点,可以被注册的Facility接收到。
再接下来,就是调用HandlerFactory来创建一个IHandler,IHandler的主要功能就是创建组件的激活器(Activator),每个组件都对应一个Activator,Activator根据Lifestyle管理器来创建不同生命类型的组件实例,比如Singleton,PreThread,Transient等等。
然后在EnsureDependenciesCanBeSatisfied()这个方法中检查组件的依赖是否都得到了满足,这里就是自动连接的原理,假如没有满足,Castle就循环检查以前注册的每个组件是否满足该组件的要求,或者该组件是否满足以前注册的组件的要求,假如满足就添加到组件的依赖列表中。
最后,注册IHandler,激发Registed事件(另一个扩展点),完成整个组件的注册过程。

 

 

posted on 2005-08-02 15:44 linkin 阅读(2140) 评论(24)  编辑 收藏 收藏至365Key
-->
FeedBack:
# re: Castle的IoC容器深入分析
2005-08-02 16:33 | linkcd
刚想写ioc的东西就看到这篇,呵呵
  
# re: Castle的IoC容器深入分析
2005-08-02 16:47 | 蛙蛙池塘
反转控制?不是java 的东西吗?
  
# re: Castle的IoC容器深入分析
2005-08-02 16:49 | linkcd
◎蛙蛙池塘
这东西重要的是思路,不在于用啥语言实现
  
# re: Castle的IoC容器深入分析
2005-08-02 16:50 | 双鱼座
好文章!
  
# re: Castle的IoC容器深入分析
2005-08-02 17:07 | 双鱼座
Castle一直是我非常欣赏的开源项目。可惜因为项目压力没有太多时间系统研究。楼主是否可以整理出一些系统的东西出来给大家分享?
Castle的IoC容器也不是spring.net这样的垃圾可以比拟的,建议不要总是和spring.net进行比较。
  
# re: Castle的IoC容器深入分析
2005-08-02 17:18 | neuhawk
可以文档还是相当少,这个东西很有前途.
从java转过来的项目,成功的不多,所以不太看好spring.net
  
# re: Castle的IoC容器深入分析
2005-08-02 17:25 | linkin
好的,以后会对Castle的整个项目做一些介绍和分析,包括Active Record,MonoRails和各种Facility等等。
事实上,作为一个敏捷开发架构,经过我们的仔细评估,我们团队有计划采用Castle作为我们的主要开发架构,以配合我们的开发制度。
  
# re: Castle的IoC容器深入分析
2005-08-02 17:40 | 双鱼座
有关Castle的中文资料太少了,这是挑战,也是机会哦!
  
# re: Castle的IoC容器深入分析
2005-08-02 18:07 | idior
Active Record的思想有问题,其他还没看,不值得介绍。
不过spring.net确实不行,似乎只有ioc.不过它是的ioc通过.net下ComponentModual实现的, 研究一下应该有意思。 不知道castle具体是如何实现ioc的。
确实需要有人多多介绍这些东西。
  
# re: Castle的IoC容器深入分析
2005-08-02 18:21 | jjx
spring.net 的ioc是垃圾? 有什么理由?原闻其详,老实说,对我而言(或者是从java到.net的用户),理解spring(spring.net)的ioc原比castle来的简单,掌握几个核心接口的思路就行,而castle,倒是一开始会没有头绪(参见我在评测网关于castle ioc的贴子)

虽然spring.net在实用性功能上没有什么进展,但据我所知,在ioc和java的一致性和对代码精益求精到了难以表达的地步(如果你有订阅spring.net cvs的更新的话)

相对于spring.net ,个人感觉castle 的代码倒是quick and dirty的


  
# re: Castle的IoC容器深入分析
2005-08-02 19:11 | cmic
同意idior观点, spring.net除了ioc什么也没实现,而且进展太慢了,和spring比差的太多了。

  
# re: Castle的IoC容器深入分析
2005-08-02 21:41 | jjx
spring.net除了ioc什么也没实现?

spring.net 的下个版本将调度到1.0,spring.net 现在已经完成了核心构造:ioc,aop. java的spring的核心也不过这两者,另外,spring.net现在还有许多内容,像
threading pool
object navigator
web
service(包括对web service/com+/remoting的封装)

当然,data(包括transaction)部分,最常用的东西,却没有很好的去完成,其实,这里有主要两个原因
①ado.net的丰富特性.很多时候像sqlhelper之类的实用类能完成大多数功能
②1.1缺少匿名类的功能,使原来依赖接口回调的spring java版本的data部分迁移困难(到.net 2.0这将容易很多)
既然没有好的方案,不如先等等,以后再做,我倒是非常认同这个的



  
# re: Castle的IoC容器深入分析
2005-08-02 22:49 | neuhawk
不知道是否有人在项目中运中了spring.net or castle,反正我是
一直没有感用,怕不稳定.
  
# re: Castle的IoC容器深入分析
2005-08-02 23:13 | linkin
spring.net确实也有可取之处,但是就是发展太慢了,而castle则非常活跃,代码每天都有大量的更新,邮件列表也讨论得很热闹。
另外一个问题就是spring.net的java影子太重了,反而没有很好的去考虑用.net的特性和优势去改进。
castle的另一个优势是非常的全面,从数据访问框架到IOC容器,再到WEB框架,完全可以只采用castle构建全部的开发。
  
# re: Castle的IoC容器深入分析
2005-08-03 09:00 | DotNetFresh
TO idior:
你说道:"Active Record的思想有问题",能否详细一点.根据这段时间我使用AR来看,我觉得AR很好,完全比用起nhibernate来舒服很多,没有一大堆的映射文件要写,用几个特性就搞定了.而且我用AR把一对多,多对一,多对多的关系都实现了,代码非常简单.难道你是指的AR的实体操作没有和实体分开这种思想不好?还是???望闻其详.
  
# re: Castle的IoC容器深入分析
2005-08-03 09:33 | linkin
我不认为Active Record的思想有问题,Martin Fowler已经在企业应用架构模式中详细的说明了Active Record的优点和设计适用性,AR在95%的情况下是够用的。并且在Castle的AR中,还可以直接执行HQL,这样一来,剩下的5%也被解决掉了。
  
# re: Castle的IoC容器深入分析
2005-08-03 09:37 | idior
我主要觉得业务对象和persistence关系太紧密, 不利于关注点分离.
Hibernate好不容易实现的透明性被破坏了.
http://idior.cnblogs.com/articles/195193.html

当然这是个人观点, 在易用性上,它是有好处的,不然人家也不去做了, 只是不看好它.

我不是说AR不好,而是说Castle的这种做法有问题.
Martin Fowler是在介绍AR之后才介绍 Data Mapper的, 估计他也没想到会有人用Data Mapper来实现AR. 如果这个Data Mapper是你做的, 你绝对不会用它去实现AR, 返祖啊?
  
# re: Castle的IoC容器深入分析
2005-08-03 09:53 | linkin
原来我们也有你的这种困惑,但是实际上我们发现这种紧密性可以通过结构设计来分开,举例:
class EntityDAO
{
public void Save(Entity entity)
{
entity.Save();
}
}
  
# re: Castle的IoC容器深入分析
2005-08-03 09:58 | idior
@linkin
DAO模式并没有解决问题,只不过把依赖变成了较弱的接口依赖.
看看这篇文章
http://idior.cnblogs.com/articles/195193.html

而且在castle的AR中好像还没有使用DAO吧.
  
# re: Castle的IoC容器深入分析
2005-08-03 10:06 | DotNetFresh
说到这点,让我想起我前段时间的一个疑惑:我一直迷惑于Castle的AR和MARTIN所说的AR.我现在是这样理解的:MARTIN的AR是一种概念,是一个模式,所以他是介绍完AR才介绍DATA MAPPER的,当然如果用DATA MAPPER去实现AR,那这确实有点返祖的意思.但是,在CASTLE里面的AR,不是MARTIN所说的AR,我觉得他是MARTIN-AR的一种实现,感觉就象DATA MAPPER一样,但是在Castle里面,他把他命名为Active Record,这就是造成我刚开始迷惑的原因---个人理解,还未更深入学习,如有不妥之处,还望指教!
  
# re: Castle的IoC容器深入分析
2005-08-03 10:11 | linkin
Transparent persistence就可以完全解决问题吗?
就算Hibernate可以自动检测对象的变化,但是这个Entity总要通过某种方式注册到Hibernate中吧?这不是同样(或许弱一些)的依赖?
DAO只是方式,AR也可以用DAO的方式来组织。
  
# re: Castle的IoC容器深入分析
2005-08-03 10:28 | idior
当然不可能完全没有依赖, 就象你使用DAO来减少依赖,Transparent persistence则是更近一步减少.
我强调一下我的观点, 我没有说AR不好(有的它应用场合,甚至还很多),但是Castle的AR(不是指AR这个概念)设计思路是值得怀疑的.

  
# re: Castle的IoC容器深入分析
2005-08-20 19:44 | IT
有人讲讲容器的应用吧!!
我很喜欢这门技术
  
# re: Castle的IoC容器深入分析
2005-12-29 11:58 | 相飞
这里我有个地方不明白的,用IOC主要是为了脱藕吧。但是在添加组件时要知道组件的类型,没法达到扩充呀。请大家指教。




















posted on 2006-03-21 14:42  Arlen  阅读(434)  评论(0编辑  收藏  举报

导航