现在的位置: 首页 > 综合 > 正文

Castle Windsor

2014年09月05日 ⁄ 综合 ⁄ 共 2394字 ⁄ 字号 评论关闭

Windsor是Castle 的一个IOC容器。它构建于MicroKernel之上,功能非常之强大,能检测类并了解使用这些类时需要什么参数,检测类型和类型之间工作依赖性,并提供服务(requirements )或者发生错误时提供预警的机制(fail fast )。
MicroKernel仅仅是提供了一个IOC的容器,非常的轻巧,它只依赖于Castle.Model一个程序集,但它的可扩展能力却很强,后面会讲到;可以这么理解,WindsorContainer为我们提供了一个Façade,它封装了MicroKernel,并且提供了一些扩展点,但它的核心仍然是Microkernel。如下图所示:

图片
既然MicroKernel是WindsorContainer的核心,那我们就来看一下MicroKernel的结构,从下面的结构图中,可以看到MicroKernel的组成主要有SubSystem,Components,Facilities几个部分,SubSystem主要用来处理一些扩展功能,如配置、类型转换等,我们也可以实现自己的SubSystem;Components称为组件,在快速入门指南中我已经提到了,这里再说一下,服务是一个个的接口,接口约定了服务,从而使随意替换服务的实现对使用接口服务的代码没有任何的影响,组件是一个可重用的程序单元,它实现了某个接口,并仅仅只实现了这一个良好的接口,也就是说,组件是实现了某个服务接口的类;Facilities我们称之为扩张单元,如果我们想扩张容器的功能,可以通过创建扩张单元来实现,我们可以在扩张单元里面订阅容器事件,给组件附加属性,建立拦截器,控制组件生命周期等,扩张单元是以一种插件的形式存在的,所以非常便于扩展,可以编写自己的扩张单元,后面我会写Castle自带的一些扩张单元的使用。MicroKernel的结构如下图: 图片

第一个Castle程序中我们获取容器时,是直接将容器实例化的。
IWindsorContainer container = new WindsorContainer();
缺省的情况下,Windsor将尝试从与AppDomain关联的XML文件中获取组件的配置信息。你也可以通过实现IConfigurationStore来取代它。当你需要配置测试环境或在其它产品等上使用其它区别于标准的XML配置读取方式可能更好。

一、组件的加载: 组件的风格,Castle.Windsor中推荐每个组件至少包括一个接口类和一个实现类。 
如组件IFileDownloader, 就包括接口类IFileDownloader和实现类HttpFileDownloader。 配置文件比较简化的情况如下,在元素下,包含元素,需要加载的组件都可以写在元素中,一个组件为一个元素。其中id为,组件的标识(在一个容器中必须唯一),service为接口的类型,type为实现类的类型。

加载的方法有两种方式:

一是采用Windsor提供的XmlInterpreter类自动读取并解析配置文件,然后你可以使用new WindsorContainer()来创建容器, 此时配置文件中的组件将注册到容器中了。这种方式对于入门者来说比较简单,(但是深入以后会发现它对于你应用系统的高级特征的实现会有不利影响),只要你按照上面的配置文件格式写,系统就可以自动注册你的组件。请注意,此时你的组件并没有运行,因为new WindsorContainer()并不会自动调用你组件的构造函数。需要你自己去显式的实例化组件。

当然,对于采用IoC方式加载的应用,启动程序是不会知道"HttpFileDownloader"这个组件的名称,这就需要你通过轮询已经注册的组件集合,从中查询出组件名称来。这个集合存放在Kernel.GraphNodes当中。 

还有一点很重要,组件注册时缺省采用单例方式,这样你每次从IFileDownloaderserver = (IFileDownloader)container"HttpFileDownloader";得到的实例都是同一个,你可以放心使用它。如果你希望使用多线程方式,就需要在组成时使用lifecycle参数,这时候取出的组件就不再是同一 个了。

另外一种方式,在启动程序中自己解析配置文件,逐个组件注册,这种方法比较灵活。但需要自己写配置文件的解析程序。

IWindsorContainer container = new WindsorContainer();

container.AddComponent("HttpFileDownloader", typeof(IFileDownloader), typeof(HttpFileDownloader));
container.AddComponent("StringParsingTitleScraper", typeof(ITitleScraper), typeof(StringParsingTitleScraper));
container.AddComponent("HtmlTitleRetriever", typeof(HtmlTitleRetriever));


二、组件的卸载 Windsor项目中给出的例子程序中并没有给出如何卸载组件, 也许大多数应用都只是创建组件,而在应用销毁时注销吧。由于Windsor对于组件的加载实质是注册,并没有真正运行,这样虽然可以采用Release()方法释放掉组件的实例,组件的注册信息还在,所以重新调用AddComponent是,Windsor会报错,告诉你组件已经存在。并且容器中没有提供方法进行反注册。但是,Windsor的容器却提供了Dispose()方法,让我们可以释放掉所有容器中已经注册的组件。可以将相关的组件放在一个容器当中,卸载时同时卸载,加载时一起加载。这个问题就解决了。

 

抱歉!评论已关闭.