|
本文引自: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 == null) throw new ArgumentNullException("key"); if (serviceType == null) throw new ArgumentNullException("serviceType"); if (classType == null) throw 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:
2005-08-02 16:33 |
刚想写ioc的东西就看到这篇,呵呵
2005-08-02 16:47 |
反转控制?不是java 的东西吗?
2005-08-02 16:49 |
◎蛙蛙池塘 这东西重要的是思路,不在于用啥语言实现
2005-08-02 16:50 |
好文章!
2005-08-02 17:07 |
Castle一直是我非常欣赏的开源项目。可惜因为项目压力没有太多时间系统研究。楼主是否可以整理出一些系统的东西出来给大家分享? Castle的IoC容器也不是spring.net这样的垃圾可以比拟的,建议不要总是和spring.net进行比较。
2005-08-02 17:18 |
可以文档还是相当少,这个东西很有前途. 从java转过来的项目,成功的不多,所以不太看好spring.net
2005-08-02 17:25 |
好的,以后会对Castle的整个项目做一些介绍和分析,包括Active Record,MonoRails和各种Facility等等。 事实上,作为一个敏捷开发架构,经过我们的仔细评估,我们团队有计划采用Castle作为我们的主要开发架构,以配合我们的开发制度。
2005-08-02 17:40 |
有关Castle的中文资料太少了,这是挑战,也是机会哦!
2005-08-02 18:07 |
Active Record的思想有问题,其他还没看,不值得介绍。 不过spring.net确实不行,似乎只有ioc.不过它是的ioc通过.net下ComponentModual实现的, 研究一下应该有意思。 不知道castle具体是如何实现ioc的。 确实需要有人多多介绍这些东西。
2005-08-02 18:21 |
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的
2005-08-02 19:11 |
同意idior观点, spring.net除了ioc什么也没实现,而且进展太慢了,和spring比差的太多了。
2005-08-02 21:41 |
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这将容易很多) 既然没有好的方案,不如先等等,以后再做,我倒是非常认同这个的
2005-08-02 22:49 |
不知道是否有人在项目中运中了spring.net or castle,反正我是 一直没有感用,怕不稳定.
2005-08-02 23:13 |
spring.net确实也有可取之处,但是就是发展太慢了,而castle则非常活跃,代码每天都有大量的更新,邮件列表也讨论得很热闹。 另外一个问题就是spring.net的java影子太重了,反而没有很好的去考虑用.net的特性和优势去改进。 castle的另一个优势是非常的全面,从数据访问框架到IOC容器,再到WEB框架,完全可以只采用castle构建全部的开发。
2005-08-03 09:00 |
TO idior: 你说道:"Active Record的思想有问题",能否详细一点.根据这段时间我使用AR来看,我觉得AR很好,完全比用起nhibernate来舒服很多,没有一大堆的映射文件要写,用几个特性就搞定了.而且我用AR把一对多,多对一,多对多的关系都实现了,代码非常简单.难道你是指的AR的实体操作没有和实体分开这种思想不好?还是???望闻其详.
2005-08-03 09:33 |
我不认为Active Record的思想有问题,Martin Fowler已经在企业应用架构模式中详细的说明了Active Record的优点和设计适用性,AR在95%的情况下是够用的。并且在Castle的AR中,还可以直接执行HQL,这样一来,剩下的5%也被解决掉了。
2005-08-03 09:37 |
我主要觉得业务对象和persistence关系太紧密, 不利于关注点分离. Hibernate好不容易实现的透明性被破坏了. http://idior.cnblogs.com/articles/195193.html 当然这是个人观点, 在易用性上,它是有好处的,不然人家也不去做了, 只是不看好它. 我不是说AR不好,而是说Castle的这种做法有问题. Martin Fowler是在介绍AR之后才介绍 Data Mapper的, 估计他也没想到会有人用Data Mapper来实现AR. 如果这个Data Mapper是你做的, 你绝对不会用它去实现AR, 返祖啊?
2005-08-03 09:53 |
原来我们也有你的这种困惑,但是实际上我们发现这种紧密性可以通过结构设计来分开,举例: class EntityDAO { public void Save(Entity entity) { entity.Save(); } }
2005-08-03 10:06 |
说到这点,让我想起我前段时间的一个疑惑:我一直迷惑于Castle的AR和MARTIN所说的AR.我现在是这样理解的:MARTIN的AR是一种概念,是一个模式,所以他是介绍完AR才介绍DATA MAPPER的,当然如果用DATA MAPPER去实现AR,那这确实有点返祖的意思.但是,在CASTLE里面的AR,不是MARTIN所说的AR,我觉得他是MARTIN-AR的一种实现,感觉就象DATA MAPPER一样,但是在Castle里面,他把他命名为Active Record,这就是造成我刚开始迷惑的原因---个人理解,还未更深入学习,如有不妥之处,还望指教!
2005-08-03 10:11 |
Transparent persistence就可以完全解决问题吗? 就算Hibernate可以自动检测对象的变化,但是这个Entity总要通过某种方式注册到Hibernate中吧?这不是同样(或许弱一些)的依赖? DAO只是方式,AR也可以用DAO的方式来组织。
2005-08-03 10:28 |
当然不可能完全没有依赖, 就象你使用DAO来减少依赖,Transparent persistence则是更近一步减少. 我强调一下我的观点, 我没有说AR不好(有的它应用场合,甚至还很多),但是Castle的AR(不是指AR这个概念)设计思路是值得怀疑的.
2005-08-20 19:44 |
有人讲讲容器的应用吧!! 我很喜欢这门技术
2005-12-29 11:58 |
这里我有个地方不明白的,用IOC主要是为了脱藕吧。但是在添加组件时要知道组件的类型,没法达到扩充呀。请大家指教。
|
|