博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Castle IOC容器实践之FactorySupport Facility
阅读量:6004 次
发布时间:2019-06-20

本文共 8088 字,大约阅读时间需要 26 分钟。

摘要: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.gif
{
InBlock.gif    
void Display();
ExpandedBlockEnd.gif}
None.gif
None.gif
public
 
class
 MyComponent : IComponent
None.gif
ExpandedBlockStart.gif
{
InBlock.gif    
public MyComponent()
InBlock.gif
ExpandedSubBlockStart.gif    
{   
InBlock.gif
ExpandedSubBlockEnd.gif    }
InBlock.gif
InBlock.gif    
public void Display()
InBlock.gif
ExpandedSubBlockStart.gif    
{
InBlock.gif        Console.WriteLine(
"MyComponentdot.gifdot.gif");
ExpandedSubBlockEnd.gif    }
ExpandedBlockEnd.gif}
None.gif
None.gif
public
 
class
 MyFactory
None.gif
ExpandedBlockStart.gif
{
InBlock.gif    
public MyFactory()
InBlock.gif
ExpandedSubBlockStart.gif    
{
InBlock.gif
ExpandedSubBlockEnd.gif    }
InBlock.gif
InBlock.gif    
public IComponent Create()
InBlock.gif
ExpandedSubBlockStart.gif    
{
InBlock.gif        
return new MyComponent();
ExpandedSubBlockEnd.gif    }
ExpandedBlockEnd.gif}
现在要在程序中使用 MyComponent的实例,简单一点会这样去写:

None.gif
public
 
class
 App
None.gif
ExpandedBlockStart.gif
{
InBlock.gif    
static void Main()
InBlock.gif
ExpandedSubBlockStart.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.gif
{
InBlock.gif    
void Display();
ExpandedBlockEnd.gif}
None.gif
None.gif
None.gif
public
 
class
 MyComponent : IComponent
None.gif
ExpandedBlockStart.gif
{
InBlock.gif    
public MyComponent()
InBlock.gif
ExpandedSubBlockStart.gif    
{
InBlock.gif
ExpandedSubBlockEnd.gif    }
InBlock.gif
InBlock.gif    
public void Display()
InBlock.gif
ExpandedSubBlockStart.gif    
{
InBlock.gif        Console.WriteLine(
"MyComponentdot.gifdot.gif");
ExpandedSubBlockEnd.gif    }
ExpandedBlockEnd.gif}
None.gif
None.gif
public
 
class
 MyFactory
None.gif
ExpandedBlockStart.gif
{
InBlock.gif    
public MyFactory()
InBlock.gif
ExpandedSubBlockStart.gif    
{
InBlock.gif
ExpandedSubBlockEnd.gif    }
InBlock.gif
InBlock.gif    
public IComponent Create()
InBlock.gif
ExpandedSubBlockStart.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.gif
{
InBlock.gif    
static void Main()
InBlock.gif
ExpandedSubBlockStart.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.gif
{
InBlock.gif    
private static readonly SingletonWithAccessor instance = new SingletonWithAccessor();
InBlock.gif
InBlock.gif    
private SingletonWithAccessor()
InBlock.gif
ExpandedSubBlockStart.gif    
{
InBlock.gif
ExpandedSubBlockEnd.gif    }
InBlock.gif
InBlock.gif    
public static SingletonWithAccessor Instance
InBlock.gif
ExpandedSubBlockStart.gif    
{
ExpandedSubBlockStart.gif        
get return 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.gif
{
InBlock.gif    
public MyComp()
InBlock.gif
ExpandedSubBlockStart.gif    
{
InBlock.gif
ExpandedSubBlockEnd.gif    }
ExpandedBlockEnd.gif}
None.gif
None.gif
public
 
class
 MyCompFactory
None.gif
ExpandedBlockStart.gif
{
InBlock.gif    
public MyComp Create()
InBlock.gif
ExpandedSubBlockStart.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.gif
{
InBlock.gif    
private string storeName;
InBlock.gif
InBlock.gif    
private IDictionary props;
InBlock.gif
InBlock.gif    
internal MyComp()
ExpandedSubBlockStart.gif    
{
InBlock.gif
ExpandedSubBlockEnd.gif    }
InBlock.gif
InBlock.gif    
internal MyComp(String storeName, IDictionary props)
InBlock.gif
ExpandedSubBlockStart.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.gif    
{
ExpandedSubBlockStart.gif        
get return storeName; }
ExpandedSubBlockEnd.gif    }
InBlock.gif
InBlock.gif    
public IDictionary Props
InBlock.gif
ExpandedSubBlockStart.gif    
{
ExpandedSubBlockStart.gif        
get return props; }
ExpandedSubBlockEnd.gif    }
ExpandedBlockEnd.gif}
None.gif
None.gif
public
 
class
 MyCompFactory2
None.gif
ExpandedBlockStart.gif
{
InBlock.gif    
public MyCompFactory2()
InBlock.gif
ExpandedSubBlockStart.gif    
{
InBlock.gif
ExpandedSubBlockEnd.gif    }
InBlock.gif
InBlock.gif    
public MyComp Create(String storeName, IDictionary props)
InBlock.gif
ExpandedSubBlockStart.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.gif
{
InBlock.gif
ExpandedBlockEnd.gif}
None.gif
None.gif
public
 
class
 MyComp
None.gif
ExpandedBlockStart.gif
{
InBlock.gif    
private IMyService serv;
InBlock.gif
InBlock.gif    
internal MyComp()
InBlock.gif
ExpandedSubBlockStart.gif    
{
InBlock.gif
ExpandedSubBlockEnd.gif    }
InBlock.gif
InBlock.gif    
internal MyComp(IMyService serv)
InBlock.gif
ExpandedSubBlockStart.gif    
{
InBlock.gif        
this.serv = serv;
ExpandedSubBlockEnd.gif    }
InBlock.gif
InBlock.gif    
public IMyService Service
InBlock.gif
ExpandedSubBlockStart.gif    
{
ExpandedSubBlockStart.gif        
get return serv; }
ExpandedSubBlockEnd.gif    }
ExpandedBlockEnd.gif}
None.gif
None.gif
public
 
class
 MyCompFactory3
None.gif
ExpandedBlockStart.gif
{
InBlock.gif    
public MyCompFactory3()
InBlock.gif
ExpandedSubBlockStart.gif    
{
InBlock.gif
ExpandedSubBlockEnd.gif    }
InBlock.gif
InBlock.gif    
public MyComp Create(IMyService serv)
InBlock.gif
ExpandedSubBlockStart.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.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.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的文章您可以访问《 》。

 

PDF版本下载

示例代码下载
本文转自lihuijun51CTO博客,原文链接:
http://blog.51cto.com/terrylee/67692
 ,如需转载请自行联系原作者
你可能感兴趣的文章
Vue笔记(五)——Token&生命周期
查看>>
《前端十年心路-我把一切告诉你》的书稿大纲&问题收集
查看>>
CSS居中总结大全
查看>>
Elasticsearch 参考指南(安装X-Pack)
查看>>
[LintCode] 604. Design Compressed String Iterator
查看>>
微信小程序黑客马拉松即将开始,来做最酷的 Mini Program Creators!
查看>>
JavaScript基础---函数
查看>>
前端每日实战:120# 视频演示如何用纯 CSS 创作锡纸撕开的文字效果
查看>>
Laravel实用小功能
查看>>
Linux系统上传下载工具rz/sz
查看>>
matplotlib绑定到PyQt5(有菜单)
查看>>
利用Powershell和ceye.io实现Windows账户密码回传
查看>>
如何清理EBS R12 middle-tier cache
查看>>
Windows 8.1 今年 1 月市场份额超 Vista
查看>>
《设计团队协作权威指南》—第1章1.5节总结
查看>>
【PMP认证考试之个人总结】第 5 章 项目时间管理
查看>>
Chair:支付宝前端团队推出的Node.js Web框架
查看>>
port-forward v1.0.1 发布,端口转发工具
查看>>
《Total Commander:万能文件管理器》——第3.8节.后续更新
查看>>
BSD vi/vim 命令大全(下)[转]
查看>>