Castle IOC容器实践之FactorySupport Facility

本文介绍了Castle Windsor中的FactorySupportFacility,它允许使用现有工厂创建组件实例,并通过配置文件将其加入容器实现自动装配。文中提供了多种配置示例,包括访问器配置、普通工厂配置等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

摘要:FactorySupport Facility允许我们使用已经存在的工厂来创建组件的实例,可以把已经存在的对象模型加入到容器中,以便它能够使用自动装配。它使用了以下两种处理策略:

1.使用访问器来访问组件的实例

2.使用静态方法或者实例方式来访问组件的实例

 

主要内容

1.概述

2.为什么需要FactorySupport Facility

3.如何使用

4.常见的配置示例

5.实现原理浅析

 

一.概述

FactorySupport Facility允许我们使用已经存在的工厂来创建组件的实例,可以把已经存在的对象模型加入到容器中,以便它能够使用自动装配。它使用了以下两种处理策略:

1.通过访问器来访问组件的实例

2.通过静态方法或者实例方式来访问组件的实例

二.为什么需要FactorySupport Facility

为了回答这个问题,我们先来看一个简单的使用工厂的例子,如下代码所示:

None.gif public   interface  IComponent 
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
void Display();
ExpandedBlockEnd.gif}

None.gif
None.gif
public   class  MyComponent : IComponent
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public MyComponent()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{   
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public void Display()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        Console.WriteLine(
"MyComponentdot.gifdot.gif");
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif
public   class  MyFactory
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public MyFactory()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public IComponent Create()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
return new MyComponent();
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

现在要在程序中使用MyComponent的实例,简单一点会这样去写:

None.gif public   class  App
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
static void Main()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        MyFactory factory 
= new MyFactory();
InBlock.gif
InBlock.gif        IComponent comp 
= factory.Create();
InBlock.gif
InBlock.gif        comp.Display();
InBlock.gif
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

正如你所看到的,在程序中使用new关键字创建了一个工厂的实例,再由工厂得到组件的实例。现在我们看使用FactorySupport Facility后带来了什么好处。工厂和组件的代码不变,仍然是:

None.gif public   interface  IComponent 
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
void Display();
ExpandedBlockEnd.gif}

None.gif
None.gif
None.gif
public   class  MyComponent : IComponent
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public MyComponent()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public void Display()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        Console.WriteLine(
"MyComponentdot.gifdot.gif");
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif
public   class  MyFactory
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public MyFactory()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public IComponent Create()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
return new MyComponent();
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

配置文件,现在你可以不用理解怎么去配置,后面会讲到。

None.gif <? xml version="1.0" encoding="utf-8"  ?>
None.gif
None.gif
< configuration >
None.gif
None.gif    
< facilities >
None.gif
None.gif        
< facility  id ="factorysupport"  type ="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel"   />
None.gif
None.gif    
</ facilities >
None.gif
None.gif    
< components >
None.gif
None.gif        
< component  id ="myfactory"  type ="FactorySupportDemo.MyFactory,FactorySupportDemo"   />
None.gif
None.gif        
< component  id ="mycomp"  type ="FactorySupportDemo.MyComponent,FactorySupportDemo"
None.gif
None.gif            factoryId
="myfactory"  factoryCreate ="Create" ></ component >
None.gif
None.gif    
</ components >
None.gif
None.gif
</ configuration >

使用组件的实例

None.gif public   class  App
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
static void Main()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        IWindsorContainer container 
= new WindsorContainer("../../Basic.xml");
InBlock.gif
InBlock.gif
InBlock.gif        IComponent instance 
= (IComponent) container["mycomp"];
InBlock.gif
InBlock.gif        instance.Display();
InBlock.gif
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

看到了吗?我们并没有使用new关键字创建任何对象,只是把工厂、组件等通过配置文件抛给了IOC容器,再从容器中往外取的时候,就可以直接取到组件的实例,这些实例是由工厂自动创建的,这正是FactorySupport Facility的作用。

三.如何使用

知道了为什么需要FactorySupport Facility之后,下面就来看如何使用Facility。在前面的代码中大家都已经看到了,使用FactorySupport Facility是非常的简单。

1.加入FactorySupport Facility到容器中,可以使用代码加入也可以使用配置文件。

使用代码加入:

None.gif IWindsorContainer container  =   new  WindsorContainer( " ../../Basic.xml " );
None.gif
None.gif
None.gifcontainer.AddFacility(
" factorysupport " , new  Castle.Facilities.FactorySupport.FactorySupportFacility());

使用配置文件:

None.gif < facilities >
None.gif
None.gif    
< facility  id ="factorysupport"  type ="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel"   />
None.gif
None.gif
</ facilities >

2.加入组件时指定使用的是哪种方式

如果使用访问器只需要指定访问器的名称就可以了:

None.gif < component  id ="accessor.comp"  
None.gif
None.gif    type
="Castle.Facilities.FactorySupport.Tests.Components.SingletonWithAccessor, Castle.Facilities.FactorySupport.Tests"
None.gif
None.gif    instance-accessor
="Instance" >
None.gif
None.gif
</ component >

如果使用工厂方法,需要指定工厂ID和工厂方法:

None.gif < component  id ="mycomp"  
None.gif
None.gif            type
="Castle.Facilities.FactorySupport.Tests.Components.MyComp, Castle.Facilities.FactorySupport.Tests"
None.gif
None.gif            factoryId
="mycompfactory"  factoryCreate ="Create" >
None.gif
None.gif
</ component >

四.常见的配置示例

这是一些常见的配置示例,来自于Castle自带的测试代码中。

1.访问器配置示例

有这样一个单件类

None.gif public   class  SingletonWithAccessor
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
private static readonly SingletonWithAccessor instance = new SingletonWithAccessor();
InBlock.gif
InBlock.gif    
private SingletonWithAccessor()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public static SingletonWithAccessor Instance
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn instance; }
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

配置文件如下:

None.gif <? xml version="1.0" encoding="utf-8"  ?>
None.gif
None.gif
< configuration >
None.gif
None.gif    
< facilities >
None.gif
None.gif        
< facility  id ="factorysupport"  type ="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel"   />
None.gif
None.gif    
</ facilities >
None.gif
None.gif    
< components >
None.gif
None.gif        
< component  id ="accessor.comp"  type ="Castle.Facilities.FactorySupport.Tests.Components.SingletonWithAccessor, Castle.Facilities.FactorySupport.Tests"
None.gif
None.gif            instance-accessor
="Instance" ></ component >
None.gif
None.gif    
</ components >
None.gif
None.gif
</ configuration >

2.普通工厂配置示例

组件类和工厂类如下

None.gif public   class  MyComp
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public MyComp()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif
public   class  MyCompFactory
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public MyComp Create()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
return new MyComp();
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

配置文件如下:

None.gif <? xml version="1.0" encoding="utf-8"  ?>
None.gif
None.gif
< configuration >
None.gif
None.gif    
< facilities >
None.gif
None.gif        
< facility  id ="factorysupport"  type ="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel"   />
None.gif
None.gif    
</ facilities >
None.gif
None.gif    
< components >
None.gif
None.gif        
< component  id ="mycompfactory"  type ="Castle.Facilities.FactorySupport.Tests.Components.MyCompFactory, Castle.Facilities.FactorySupport.Tests"   />
None.gif
None.gif        
< component  id ="mycomp"  type ="Castle.Facilities.FactorySupport.Tests.Components.MyComp, Castle.Facilities.FactorySupport.Tests"
None.gif
None.gif            factoryId
="mycompfactory"  factoryCreate ="Create" ></ component >
None.gif
None.gif    
</ components >
None.gif
None.gif
</ configuration >

3.带参工厂配置示例

组件类和工厂类如下:

None.gif public   class  MyComp
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
private string storeName;
InBlock.gif
InBlock.gif    
private IDictionary props;
InBlock.gif
InBlock.gif    
internal MyComp()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
internal MyComp(String storeName, IDictionary props)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
this.storeName = storeName;
InBlock.gif
InBlock.gif        
this.props = props;
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public string StoreName
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn storeName; }
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public IDictionary Props
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn props; }
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif
public   class  MyCompFactory2
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public MyCompFactory2()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public MyComp Create(String storeName, IDictionary props)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
return new MyComp(storeName, props);
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

配置文件如下:

None.gif <? xml version="1.0" encoding="utf-8"  ?>
None.gif
None.gif
< configuration >
None.gif
None.gif    
< facilities >
None.gif
None.gif        
< facility  id ="factorysupport"  type ="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel"   />
None.gif
None.gif    
</ facilities >
None.gif
None.gif    
< components >
None.gif
None.gif       
< component  id ="mycompfactory"  type ="Castle.Facilities.FactorySupport.Tests.Components.MyCompFactory2, Castle.Facilities.FactorySupport.Tests" ></ component >
None.gif
None.gif        
< component  id ="mycomp"  type ="Castle.Facilities.FactorySupport.Tests.Components.MyComp, Castle.Facilities.FactorySupport.Tests"
None.gif
None.gif            factoryId
="mycompfactory"  factoryCreate ="Create" >
None.gif
None.gif            
< parameters >
None.gif
None.gif                
< storeName > MyStore </ storeName >
None.gif
None.gif                
< props >
None.gif
None.gif                    
< dictionary >
None.gif
None.gif                        
< entry  key ="key1" > item1 </ entry >
None.gif
None.gif                        
< entry  key ="key2" > item2 </ entry >
None.gif
None.gif                    
</ dictionary >
None.gif
None.gif                
</ props >
None.gif
None.gif            
</ parameters >
None.gif
None.gif        
</ component >
None.gif
None.gif    
</ components >
None.gif
None.gif
</ configuration >

4.使用自动装配工厂配置示例

组件类和工厂类如下:

None.gif public   interface  IMyService
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
ExpandedBlockEnd.gif}

None.gif
None.gif
public   class  MyComp
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
private IMyService serv;
InBlock.gif
InBlock.gif    
internal MyComp()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
internal MyComp(IMyService serv)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
this.serv = serv;
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public IMyService Service
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn serv; }
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif
public   class  MyCompFactory3
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public MyCompFactory3()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public MyComp Create(IMyService serv)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
return new MyComp(serv);
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

配置文件如下:

None.gif <? xml version="1.0" encoding="utf-8"  ?>
None.gif
None.gif
< configuration >
None.gif
None.gif    
< facilities >
None.gif
None.gif        
< facility  id ="factorysupport"  type ="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel"   />
None.gif
None.gif    
</ facilities >
None.gif
None.gif    
< components >
None.gif
None.gif        
< component  id ="myserv"  service ="Castle.Facilities.FactorySupport.Tests.Components.IMyService, Castle.Facilities.FactorySupport.Tests"
None.gif
None.gif            type
="Castle.Facilities.FactorySupport.Tests.Components.DefaultMyService, Castle.Facilities.FactorySupport.Tests"   />
None.gif
None.gif       
< component  id ="mycompfactory"  type ="Castle.Facilities.FactorySupport.Tests.Components.MyCompFactory3, Castle.Facilities.FactorySupport.Tests" ></ component >
None.gif
None.gif        
< component  id ="mycomp"  type ="Castle.Facilities.FactorySupport.Tests.Components.MyComp, Castle.Facilities.FactorySupport.Tests"
None.gif
None.gif            factoryId
="mycompfactory"  factoryCreate ="Create" >
None.gif
None.gif            
<!--  parameters is not necessary_u97 ?s it will auto wire  --> </ component >
None.gif
None.gif    
</ components >
None.gif
None.gif
</ configuration >

五.实现原理浅析

FactorySupport Facility的实现也是非常的简单,主要是通过两个ComponentActivator来实现,分别为AccessorActivatorFactoryActivator,根据配置文件的不同调用不同的Activator

None.gif String instanceAccessor  =  model.Configuration.Attributes[ " instance-accessor " ];
None.gif
None.gifString factoryId 
=  model.Configuration.Attributes[ " factoryId " ];
None.gif
None.gifString factoryCreate 
=  model.Configuration.Attributes[ " factoryCreate " ];
None.gif
None.gif
None.gif
if  (instanceAccessor  !=   null )
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
InBlock.gif    model.ExtendedProperties.Add( 
"instance.accessor", instanceAccessor );
InBlock.gif
InBlock.gif    model.CustomComponentActivator 
= typeof(AccessorActivator);
InBlock.gif
ExpandedBlockEnd.gif}

None.gif
None.gif
else   if  (factoryId  !=   null )
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
InBlock.gif    model.ExtendedProperties.Add( 
"factoryId", factoryId );
InBlock.gif
InBlock.gif    model.ExtendedProperties.Add( 
"factoryCreate", factoryCreate );
InBlock.gif
InBlock.gif    model.CustomComponentActivator 
= typeof(FactoryActivator);
InBlock.gif
ExpandedBlockEnd.gif}

好了,关于FactorySupport Facility就介绍到这儿,更多Castle的文章您可以访问《Castle 开发系列文章》。

 

PDF版本下载/Files/Terrylee/FactorySupportFacility.rar

示例代码下载/Files/Terrylee/FactorySupportDemo.rar

 

参考资料

Castle的官方网站http://www.castleproject.org

(出处:博客园http://terrylee.cnblogs.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值