FactorySupport Facility允许我们使用已经存在的工厂来创建组件的实例,可以把已经存在的对象模型加入到容器中,以便它能够使用自动装配。它使用了以下两种处理策略:
1.使用访问器来访问组件的实例
2.使用静态方法或者实例方式来访问组件的实例
主要内容
1.概述
2.为什么需要FactorySupport Facility
3.如何使用
4.常见的配置示例
5.实现原理浅析
摘要:FactorySupport Facility允许我们使用已经存在的工厂来创建组件的实例,可以把已经存在的对象模型加入到容器中,以便它能够使用自动装配。它使用了以下两种处理策略:
1.使用访问器来访问组件的实例
2.使用静态方法或者实例方式来访问组件的实例
主要内容
1.概述
2.为什么需要FactorySupport Facility
3.如何使用
4.常见的配置示例
5.实现原理浅析
一.概述
FactorySupport Facility允许我们使用已经存在的工厂来创建组件的实例,可以把已经存在的对象模型加入到容器中,以便它能够使用自动装配。它使用了以下两种处理策略:
1.通过访问器来访问组件的实例
2.通过静态方法或者实例方式来访问组件的实例
二.为什么需要FactorySupport Facility
为了回答这个问题,我们先来看一个简单的使用工厂的例子,如下代码所示:
public interface IComponent
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
void Display();
}
![](/Images/OutliningIndicators/None.gif)
public class MyComponent : IComponent
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
public MyComponent()
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
public void Display()
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Console.WriteLine("MyComponent![](/Images/dot.gif)
");
}
}
![](/Images/OutliningIndicators/None.gif)
public class MyFactory
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
public MyFactory()
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
public IComponent Create()
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return new MyComponent();
}
}
现在要在程序中使用MyComponent的实例,简单一点会这样去写:
public class App
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
static void Main()
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
MyFactory factory = new MyFactory();
![](/Images/OutliningIndicators/InBlock.gif)
IComponent comp = factory.Create();
![](/Images/OutliningIndicators/InBlock.gif)
comp.Display();
![](/Images/OutliningIndicators/InBlock.gif)
}
}
正如你所看到的,在程序中使用new关键字创建了一个工厂的实例,再由工厂得到组件的实例。现在我们看使用FactorySupport Facility后带来了什么好处。工厂和组件的代码不变,仍然是:
public interface IComponent
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
void Display();
}
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
public class MyComponent : IComponent
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
public MyComponent()
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
public void Display()
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Console.WriteLine("MyComponent![](/Images/dot.gif)
");
}
}
![](/Images/OutliningIndicators/None.gif)
public class MyFactory
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
public MyFactory()
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
public IComponent Create()
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return new MyComponent();
}
}
配置文件,现在你可以不用理解怎么去配置,后面会讲到。
<?xml version="1.0" encoding="utf-8" ?>
![](/Images/OutliningIndicators/None.gif)
<configuration>
![](/Images/OutliningIndicators/None.gif)
<facilities>
![](/Images/OutliningIndicators/None.gif)
<facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
![](/Images/OutliningIndicators/None.gif)
</facilities>
![](/Images/OutliningIndicators/None.gif)
<components>
![](/Images/OutliningIndicators/None.gif)
<component id="myfactory" type="FactorySupportDemo.MyFactory,FactorySupportDemo" />
![](/Images/OutliningIndicators/None.gif)
<component id="mycomp" type="FactorySupportDemo.MyComponent,FactorySupportDemo"
![](/Images/OutliningIndicators/None.gif)
factoryId="myfactory" factoryCreate="Create"></component>
![](/Images/OutliningIndicators/None.gif)
</components>
![](/Images/OutliningIndicators/None.gif)
</configuration>
使用组件的实例
public class App
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
static void Main()
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
IWindsorContainer container = new WindsorContainer("../../Basic.xml");
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
IComponent instance = (IComponent) container["mycomp"];
![](/Images/OutliningIndicators/InBlock.gif)
instance.Display();
![](/Images/OutliningIndicators/InBlock.gif)
}
}
看到了吗?我们并没有使用new关键字创建任何对象,只是把工厂、组件等通过配置文件抛给了IOC容器,再从容器中往外取的时候,就可以直接取到组件的实例,这些实例是由工厂自动创建的,这正是FactorySupport Facility的作用。
三.如何使用
知道了为什么需要FactorySupport Facility之后,下面就来看如何使用Facility。在前面的代码中大家都已经看到了,使用FactorySupport Facility是非常的简单。
1.加入FactorySupport Facility到容器中,可以使用代码加入也可以使用配置文件。
使用代码加入:
IWindsorContainer container = new WindsorContainer("../../Basic.xml");
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
container.AddFacility("factorysupport",new Castle.Facilities.FactorySupport.FactorySupportFacility());
使用配置文件:
<facilities>
![](/Images/OutliningIndicators/None.gif)
<facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
![](/Images/OutliningIndicators/None.gif)
</facilities>
2.加入组件时指定使用的是哪种方式
如果使用访问器只需要指定访问器的名称就可以了:
<component id="accessor.comp"
![](/Images/OutliningIndicators/None.gif)
type="Castle.Facilities.FactorySupport.Tests.Components.SingletonWithAccessor, Castle.Facilities.FactorySupport.Tests"
![](/Images/OutliningIndicators/None.gif)
instance-accessor="Instance">
![](/Images/OutliningIndicators/None.gif)
</component>
如果使用工厂方法,需要指定工厂ID和工厂方法:
<component id="mycomp"
![](/Images/OutliningIndicators/None.gif)
type="Castle.Facilities.FactorySupport.Tests.Components.MyComp, Castle.Facilities.FactorySupport.Tests"
![](/Images/OutliningIndicators/None.gif)
factoryId="mycompfactory" factoryCreate="Create">
![](/Images/OutliningIndicators/None.gif)
</component>
四.常见的配置示例
这是一些常见的配置示例,来自于Castle自带的测试代码中。
1.访问器配置示例
有这样一个单件类
public class SingletonWithAccessor
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
private static readonly SingletonWithAccessor instance = new SingletonWithAccessor();
![](/Images/OutliningIndicators/InBlock.gif)
private SingletonWithAccessor()
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
public static SingletonWithAccessor Instance
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return instance; }
}
}
配置文件如下:
<?xml version="1.0" encoding="utf-8" ?>
![](/Images/OutliningIndicators/None.gif)
<configuration>
![](/Images/OutliningIndicators/None.gif)
<facilities>
![](/Images/OutliningIndicators/None.gif)
<facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
![](/Images/OutliningIndicators/None.gif)
</facilities>
![](/Images/OutliningIndicators/None.gif)
<components>
![](/Images/OutliningIndicators/None.gif)
<component id="accessor.comp" type="Castle.Facilities.FactorySupport.Tests.Components.SingletonWithAccessor, Castle.Facilities.FactorySupport.Tests"
![](/Images/OutliningIndicators/None.gif)
instance-accessor="Instance"></component>
![](/Images/OutliningIndicators/None.gif)
</components>
![](/Images/OutliningIndicators/None.gif)
</configuration>
2.普通工厂配置示例
组件类和工厂类如下
public class MyComp
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
public MyComp()
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
}
}
![](/Images/OutliningIndicators/None.gif)
public class MyCompFactory
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
public MyComp Create()
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return new MyComp();
}
}
配置文件如下:
<?xml version="1.0" encoding="utf-8" ?>
![](/Images/OutliningIndicators/None.gif)
<configuration>
![](/Images/OutliningIndicators/None.gif)
<facilities>
![](/Images/OutliningIndicators/None.gif)
<facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
![](/Images/OutliningIndicators/None.gif)
</facilities>
![](/Images/OutliningIndicators/None.gif)
<components>
![](/Images/OutliningIndicators/None.gif)
<component id="mycompfactory" type="Castle.Facilities.FactorySupport.Tests.Components.MyCompFactory, Castle.Facilities.FactorySupport.Tests" />
![](/Images/OutliningIndicators/None.gif)
<component id="mycomp" type="Castle.Facilities.FactorySupport.Tests.Components.MyComp, Castle.Facilities.FactorySupport.Tests"
![](/Images/OutliningIndicators/None.gif)
factoryId="mycompfactory" factoryCreate="Create"></component>
![](/Images/OutliningIndicators/None.gif)
</components>
![](/Images/OutliningIndicators/None.gif)
</configuration>
3.带参工厂配置示例
组件类和工厂类如下:
public class MyComp
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
private string storeName;
![](/Images/OutliningIndicators/InBlock.gif)
private IDictionary props;
![](/Images/OutliningIndicators/InBlock.gif)
internal MyComp()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
internal MyComp(String storeName, IDictionary props)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
this.storeName = storeName;
![](/Images/OutliningIndicators/InBlock.gif)
this.props = props;
}
![](/Images/OutliningIndicators/InBlock.gif)
public string StoreName
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return storeName; }
}
![](/Images/OutliningIndicators/InBlock.gif)
public IDictionary Props
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return props; }
}
}
![](/Images/OutliningIndicators/None.gif)
public class MyCompFactory2
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
public MyCompFactory2()
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
public MyComp Create(String storeName, IDictionary props)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return new MyComp(storeName, props);
}
}
配置文件如下:
<?xml version="1.0" encoding="utf-8" ?>
![](/Images/OutliningIndicators/None.gif)
<configuration>
![](/Images/OutliningIndicators/None.gif)
<facilities>
![](/Images/OutliningIndicators/None.gif)
<facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
![](/Images/OutliningIndicators/None.gif)
</facilities>
![](/Images/OutliningIndicators/None.gif)
<components>
![](/Images/OutliningIndicators/None.gif)
<component id="mycompfactory" type="Castle.Facilities.FactorySupport.Tests.Components.MyCompFactory2, Castle.Facilities.FactorySupport.Tests"></component>
![](/Images/OutliningIndicators/None.gif)
<component id="mycomp" type="Castle.Facilities.FactorySupport.Tests.Components.MyComp, Castle.Facilities.FactorySupport.Tests"
![](/Images/OutliningIndicators/None.gif)
factoryId="mycompfactory" factoryCreate="Create">
![](/Images/OutliningIndicators/None.gif)
<parameters>
![](/Images/OutliningIndicators/None.gif)
<storeName>MyStore</storeName>
![](/Images/OutliningIndicators/None.gif)
<props>
![](/Images/OutliningIndicators/None.gif)
<dictionary>
![](/Images/OutliningIndicators/None.gif)
<entry key="key1">item1</entry>
![](/Images/OutliningIndicators/None.gif)
<entry key="key2">item2</entry>
![](/Images/OutliningIndicators/None.gif)
</dictionary>
![](/Images/OutliningIndicators/None.gif)
</props>
![](/Images/OutliningIndicators/None.gif)
</parameters>
![](/Images/OutliningIndicators/None.gif)
</component>
![](/Images/OutliningIndicators/None.gif)
</components>
![](/Images/OutliningIndicators/None.gif)
</configuration>
4.使用自动装配工厂配置示例
组件类和工厂类如下:
public interface IMyService
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/None.gif)
public class MyComp
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
private IMyService serv;
![](/Images/OutliningIndicators/InBlock.gif)
internal MyComp()
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
internal MyComp(IMyService serv)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
this.serv = serv;
}
![](/Images/OutliningIndicators/InBlock.gif)
public IMyService Service
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return serv; }
}
}
![](/Images/OutliningIndicators/None.gif)
public class MyCompFactory3
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
public MyCompFactory3()
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
public MyComp Create(IMyService serv)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return new MyComp(serv);
}
}
配置文件如下:
<?xml version="1.0" encoding="utf-8" ?>
![](/Images/OutliningIndicators/None.gif)
<configuration>
![](/Images/OutliningIndicators/None.gif)
<facilities>
![](/Images/OutliningIndicators/None.gif)
<facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
![](/Images/OutliningIndicators/None.gif)
</facilities>
![](/Images/OutliningIndicators/None.gif)
<components>
![](/Images/OutliningIndicators/None.gif)
<component id="myserv" service="Castle.Facilities.FactorySupport.Tests.Components.IMyService, Castle.Facilities.FactorySupport.Tests"
![](/Images/OutliningIndicators/None.gif)
type="Castle.Facilities.FactorySupport.Tests.Components.DefaultMyService, Castle.Facilities.FactorySupport.Tests" />
![](/Images/OutliningIndicators/None.gif)
<component id="mycompfactory" type="Castle.Facilities.FactorySupport.Tests.Components.MyCompFactory3, Castle.Facilities.FactorySupport.Tests"></component>
![](/Images/OutliningIndicators/None.gif)
<component id="mycomp" type="Castle.Facilities.FactorySupport.Tests.Components.MyComp, Castle.Facilities.FactorySupport.Tests"
![](/Images/OutliningIndicators/None.gif)
factoryId="mycompfactory" factoryCreate="Create">
![](/Images/OutliningIndicators/None.gif)
<!-- parameters is not necessary_u97 ?s it will auto wire --></component>
![](/Images/OutliningIndicators/None.gif)
</components>
![](/Images/OutliningIndicators/None.gif)
</configuration>
五.实现原理浅析
FactorySupport Facility的实现也是非常的简单,主要是通过两个ComponentActivator来实现,分别为AccessorActivator和FactoryActivator,根据配置文件的不同调用不同的Activator。
String instanceAccessor = model.Configuration.Attributes["instance-accessor"];
![](/Images/OutliningIndicators/None.gif)
String factoryId = model.Configuration.Attributes["factoryId"];
![](/Images/OutliningIndicators/None.gif)
String factoryCreate = model.Configuration.Attributes["factoryCreate"];
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
if (instanceAccessor != null)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
model.ExtendedProperties.Add( "instance.accessor", instanceAccessor );
![](/Images/OutliningIndicators/InBlock.gif)
model.CustomComponentActivator = typeof(AccessorActivator);
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/None.gif)
else if (factoryId != null)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
model.ExtendedProperties.Add( "factoryId", factoryId );
![](/Images/OutliningIndicators/InBlock.gif)
model.ExtendedProperties.Add( "factoryCreate", factoryCreate );
![](/Images/OutliningIndicators/InBlock.gif)
model.CustomComponentActivator = typeof(FactoryActivator);
![](/Images/OutliningIndicators/InBlock.gif)
}
好了,关于FactorySupport Facility就介绍到这儿,更多Castle的文章您可以访问《Castle 开发系列文章》。
PDF版本下载:/Files/Terrylee/FactorySupportFacility.rar
示例代码下载:/Files/Terrylee/FactorySupportDemo.rar
参考资料
Castle的官方网站http://www.castleproject.org
(出处:博客园http://terrylee.cnblogs.com)