Castle揭密2----IOC(3)

   Castle IOC是Castle的核心和灵魂。有一句话是这么说的,如果要理解castle和spring这样的框架,必须首先理解其IOC。当然,如果停留在使用层次那就不需要了。本章帮你一起揭密Castle IOC本质。

接上篇的问题。先摆一个核心类图

Castle揭密2----IOC(3)_第1张图片

乖乖,那么复杂。一一分析。

IServiceProviderEx:继承自IServiceProvider,扩充了public object GetService(Type serviceType)的范型版本public T GetService<T>().这个可以看做是对.net基本类库的扩充。IWindsorContainer和IKernal均继承此接口

Ikernal: MicroKernal核心接口。Castle的核心容器是microkernal,所有基本和基础实现都在microkernal中.如容器的组件(1:component 2:facility )注入,Hanlder的创建,组件依赖关系的识别(包括配置文件方式),动态加入依赖关系,组件Resolve,组件激活,组件使用代理激活,组件各种激活方式,容器对组件生命周期的管理和各种事件,组件配置的序列化和反序列化等)

IWindsorContainer:核心接口。提供了在容器重查找,注册component的方法。同时提供操作子容器,父容器的方法。有多个重载方法,例如AddComponent,AddFacility,resolve等。

IWindsorContainer:依赖IKernal,可以看做是Ikernal的封装和扩充,四个方面的扩展(见备注)。所以IWindsorContainer具有Ikernal的所有功能IWindsorContainer

实例分析下,引用上篇的例子,首先构造一个windsorContainer,windsorContainer是IWindsorContainer的缺省实现。

   1: IWindsorContainer container = new WindsorContainer();
   2:  
   3: [Serializable]
   4:  
   5: public class WindsorContainer : MarshalByRefObject, IWindsorContainer
   6:  
   7: {
   8:  
   9: private readonly string name = Guid.NewGuid().ToString();
  10:  
  11: private readonly IDictionary childContainers = Hashtable.Synchronized(new Hashtable());
  12:  
  13: private IKernel kernel;
  14:  
  15: private IWindsorContainer parent;
  16:  
  17: private IComponentsInstaller installer;
  18:  
  19: }

调用缺省构造造器后,初始化了缺省的DefaultKernel和DefaultComponentInstaller

   1: public WindsorContainer() : this(new DefaultKernel(), new Installer.DefaultComponentInstaller())
   2:  
   3: {
   4:  
   5: }

调用到

   1: public WindsorContainer(IKernel kernel, IComponentsInstaller installer) : this(Guid.NewGuid().ToString(), kernel, installer)
   2:  
   3: {
   4:  
   5: }

给组件分配了个guid作为名字,这在父子容器中用到。继续调用到

   1: public WindsorContainer(String name, IKernel kernel, IComponentsInstaller installer)
   2:  
   3: {
   4:  
   5: this.name = name;
   6:  
   7: this.kernel = kernel;
   8:  
   9: this.kernel.ProxyFactory = new Proxy.DefaultProxyFactory();
  10:  
  11: this.installer = installer;
  12:  
  13: }

这里初始化了default的ProxyFactory(使用到了dynamicProxy)分配给defaultKernal的proxyFactory。在MicroKernal中默认是不使用proxy的(NotSupportedProxyFactory)。

容器初始化完成,其实这里的重点是对MicroKernal的初始化,new DefaultKernel(),这里涉及很多内容,后面分解,先假设默认理解最核心的Kernal已经构建好。

下面加入组件:

container.AddComponent("mailSender", typeof (IEmailSender), typeof (SmtpEmailSender)); 

AddComponent有很多重载方法,

1:serviceType =classType,

IWindsorContainer AddComponent(String key, Type classType);

2:classType是serviceType的实现类型

IWindsorContainer AddComponent(String key, Type serviceType, Type classType); 

3:加入了组件lifestyle,lifestyle概念参见第一篇

IWindsorContainer AddComponentLifeStyle(String key, Type classType, LifestyleType lifestyle); 


IWindsorContainer AddComponentLifeStyle(String key, Type serviceType, Type classType, LifestyleType lifestyle);

4:加入了一些扩展属性。用处后面解释

IWindsorContainer AddComponentWithProperties(String key, Type classType, IDictionary extendedProperties); 

IWindsorContainer AddComponentWithProperties(String key, Type serviceType, Type classType, IDictionary extendedProperties);

5:范型版本,此处key =typeof(T)

IWindsorContainer AddComponent<T>(); 

IWindsorContainer AddComponent<T>(String key);

略。。。

无论哪种方法,最终都是交给Kernal去处理。例如

public IWindsorContainer AddComponentLifeStyle(string key, Type serviceType, Type classType, LifestyleType lifestyle) 
{

kernel.AddComponent(key, serviceType, classType, lifestyle, true);
return this;
}
public IWindsorContainer AddComponentLifeStyle(string key, Type serviceType, Type classType, LifestyleType lifestyle) 
{
kernel.AddComponent(key, serviceType, classType, lifestyle, true);
return this;
}

对于AddFacility,原理一样。任何实现了IFacility接口的组件都可以被加入到容器中(castle就是依靠这个整合扩充了很多优秀的其他第三方组件啊,比如Ibastis,Log4,nHibernate,WCF…,呵呵)。下列是几个重载方法,可以加入一个缺省type =T的facility。

IWindsorContainer AddFacility(String key, IFacility facility); 

IWindsorContainer AddFacility<T>(String key) where T : IFacility, new();

IWindsorContainer AddFacility<T>() where T : IFacility, new();

获取组件:

INewsletterService newsLetterService = container["newLetter"] as INewsletterService ; 

调用了对象Index

public virtual object Resolve(String key, Type service, IDictionary arguments)
{

return kernel.Resolve(key, service, arguments);

}

 

很明显,一个根据key来获取,一个根据serviceType来获取。所以不可能加入多于一个的相同key和type的组件。对象Index调用到Resovle方法。同样,Resolve有很多重载版本,就不一一列举了。举一个例子,

public virtual object Resolve(String key, Type service, IDictionary arguments) 
{

return kernel.Resolve(key, service, arguments);

}

这里也是最终转调的Ikernal的Resolve方法。

好了,今天写到此,相信大家比以前更加了解了些。呵呵

待续。。。。。。。

注: castle的核心容器实现是MicroKernal 组件,WindsorContainer在其上做了下列方面的扩充

  1. 动态代理dyanmicProxy,这个非常重要。著名的nhiberante也在使用它,它从容器返回的是wrapper后的proxy对象,访问的时候会取到real type。Proxy的实现和remoting,AOP interpretor有关,后面会重点分析
  2. 提供Adapeter,适配System.ComponentModel.IContainer, System.ComponentModel.IComponent到Castle.Core.ComponentModel , Castle.Windsor.Adapters.ComponentModel.IWindsorContainer。后面讲再提到
  3. 提供了IComponentsInstaller 根据IConfigurationStore 对容器进行构造安装。IConfigurationStore重的IConfiguration可以是配置文件或者内存节点对象。 如DefaultComponentInstaller的setup方法
    public void SetUp(IWindsorContainer container, IConfigurationStore store) 
    {
    SetUpComponents(store.GetBootstrapComponents(), container);
    SetUpFacilities(store.GetFacilities(), container);
    SetUpComponents(store.GetComponents(), container);
    SetUpChildContainers(store.GetConfigurationForChildContainers(), container);
    }
  4. 提供了IWindsorInstaller对容器进行构造安装。缺省的实现了ConfigurationInstaller,使用配置文件进行安装。后面会再提到。

 

你可能感兴趣的:(cast)