摘要:在快速入门指南篇中,我们对于Castle IOC容器的使用已经有了一个直观的认识。本文将在这基础上进一步对Castle IOC容器的结构及其注册组件的过程做一个深入的分析,让我们开始Castle IOC的内幕故事吧。
主要内容
1
.WindsorContainer分析
2
.MicroKernel分析
3
.注册组件流程
一.WindsorContainer分析
WindsorContainer
是Castle的IOC容器,也是它的一个核心,先来看一下WindsorContainer在Castle中所处的位置:
图1
WindsorContainer
构建于
MicroKernel
之上,
MicroKernel
仅仅是提供了一个IOC的容器,非常的轻巧,它只依赖于
Castle.Model
一个程序集,但它的可扩展能力却很强,后面会讲到
;可以这么理解,
WindsorContainer
为我们提供了一个Façade,它封装了MicroKernel,并且提供了一些扩展点,但
它的核心仍然是Microkernel。
如下图所示:
图2
二.MicroKernel分析
既然MicroKernel是
WindsorContainer
的核心,那我们就来看一下
MicroKernel
的结构,从下面的结构图中,可以看到MicroKernel的组成主要有SubSystem,Components,Facilities几个部分,SubSystem主要用来处理一些扩展功能,如配置、类型转换等,我们也可以实现自己的SubSystem;Components称为组件,在快速入门指南中我已经提到了,这里再说一下,
服务是一个个的接口,接口约定了服务,从而使随意替换服务的实现对使用接口服务的代码没有任何的影响,组件是一个可重用的程序单元,它实现了某个接口,并仅仅只实现了这一个良好的接口,也就是说,组件是实现了某个服务接口的类;Facilities我们称之为扩张单元,如果我们想扩张容器的功能,可以通过创建扩张单元来实现,我们可以在扩张单元里面订阅容器事件,给组件附加属性,建立拦截器,控制组件生命周期等,扩张单元是以一种插件的形式存在的,所以非常便于扩展,可以编写自己的扩张单元,后面我会写Castle自带的一些扩张单元的使用。MicroKernel的结构如下图:
图3
三.注册组件流程
现在我们来看一下当注册一个组件时,容器做了什么?
public
virtual
void
AddComponent(String key, Type classType)
![None.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/None.gif)
{
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
_kernel.AddComponent(key, classType);
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
![None.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/None.gif)
![None.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/None.gif)
public
virtual
void
AddComponent(String key, Type serviceType, Type classType)
![None.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/None.gif)
{
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
_kernel.AddComponent(key, serviceType, classType);
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
![None.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/None.gif)
//
[url]http://terrylee.cnblogs.com[/url]
可以看到,
WindsorContainer
仅仅是调用了MicroKernel的方法来完成组件的注册,它只是对MicroKernel做了一次封装,核心的功能都由MicroKernel来完成,看一下MicroKernel中的AddComponent()方法的实现
public
virtual
void
AddComponent(String key, Type classType)
![None.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/None.gif)
{
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (key == null) throw new ArgumentNullException("key");
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (classType == null) throw new ArgumentNullException("classType");
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ComponentModel model = ComponentModelBuilder.BuildModel(key, classType, classType, null);
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
RaiseComponentModelCreated(model);
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IHandler handler = HandlerFactory.Create(model);
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
RegisterHandler(key, handler);
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
![None.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/None.gif)
![None.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/None.gif)
public
virtual
void
AddComponent(String key, Type serviceType, Type classType)
![None.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/None.gif)
{
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (key == null) throw new ArgumentNullException("key");
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (serviceType == null) throw new ArgumentNullException("serviceType");
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (classType == null) throw new ArgumentNullException("classType");
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ComponentModel model = ComponentModelBuilder.BuildModel(key, serviceType, classType, null);
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
RaiseComponentModelCreated(model);
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IHandler handler = HandlerFactory.Create(model);
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
RegisterHandler(key, handler);
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
![None.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/None.gif)
//
[url]http://terrylee.cnblogs.com[/url]
先做一些必要的异常处理,然后为当前组件创建
ComponentModel
实例,ComponentModel获取当前组件的详细元信息,而且这个信息在容器中的任何地方都可以使用,所以ComponentModel其实就是组件的一个“元信息库”。创建ComponentModel的过程如下:
public
ComponentModel BuildModel(String key, Type service,
![None.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/None.gif)
Type classType, IDictionary extendedProperties)
![None.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/None.gif)
{
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ComponentModel model = new ComponentModel(key, service, classType);
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (extendedProperties != null)
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
{
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
model.ExtendedProperties = extendedProperties;
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
foreach(IContributeComponentModelConstruction contributor in contributors)
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
{
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
contributor.ProcessModel( kernel, model );
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return model;
}
//
[url]http://terrylee.cnblogs.com[/url]
创建
ComponentModel
的过程其实就是调用contributor来对组件进行处理,它会按照顺序对添加进来的contributor依次调用,在DefaultComponentModelBuilder一共注册了八个Contributor,分别为:
protected
virtual
void
InitializeContributors()
![None.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/None.gif)
{
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
AddContributor( new ConfigurationModelInspector() );
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
AddContributor( new LifestyleModelInspector() );
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
AddContributor( new ConstructorDependenciesModelInspector() );
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
AddContributor( new PropertiesDependenciesModelInspector() );
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
AddContributor( new MethodMetaInspector() );
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
AddContributor( new LifecycleModelInspector() );
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
AddContributor( new ConfigurationParametersInspector() );
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
AddContributor( new InterceptorInspector() );
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
![None.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/None.gif)
//
[url]http://terrylee.cnblogs.com[/url]
这八个
Contributor形成了一个处理组件的流程,它们涵盖了组件处理流程中的配置,生命周期,构造函数依赖,属性依赖等方面,每一个
Contributor只负责某一方面的事情。再下来一步就是发出
ComponentModelCreated事件了,这步的操作很简单
protected
virtual
void
RaiseComponentModelCreated(ComponentModel model)
![None.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/None.gif)
{
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ComponentModelDelegate eventDelegate = (ComponentModelDelegate) events[ComponentModelCreatedEvent];
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (eventDelegate != null) eventDelegate(model);
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
![None.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/None.gif)
//
[url]http://terrylee.cnblogs.com[/url]
现在
ComponentModel创建完成,该是创建
IHandler了,
IHandler并不做创建组件的工作,它主要的功能是创建
ComponentActivator,而
ComponentActivator则是完成容器的组件创建工作,它首先会根据
ComponentModel“信息库”检查相关的依赖,检查通过后根据生命周期管理来创建不同类型的组件,创建
DefaultHandler的代码如下:
public
virtual
IHandler Create(ComponentModel model)
![None.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/None.gif)
{
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IHandler handler = new DefaultHandler(model);
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
handler.Init(kernel);
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return handler;
![InBlock.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
![None.gif](http://terrylee.cnblogs.com/Images/OutliningIndicators/None.gif)
//
[url]http://terrylee.cnblogs.com[/url]
最后发出
ComponentRegistered
、HandlerRegistered事件,完成整个组件的注册过程。
参考资料
Castle的官方网站[url]http://www.castleproject.org[/url]
本文转自lihuijun51CTO博客,原文链接:http://blog.51cto.com/terrylee/67672 ,如需转载请自行联系原作者