开发者社区> 技术小甜> 正文

Castle IOC容器实践之FactorySupport Facility

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

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

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

 

主要内容

1.概述

2.为什么需要FactorySupport Facility

3.如何使用

4.常见的配置示例

5.实现原理浅析

 

一.概述

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

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

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

二.为什么需要FactorySupport Facility

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

None.gifpublic 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.gifpublic 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.gifpublic 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.gifpublic 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.gifIWindsorContainer 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.gifpublic 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.gifpublic 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.gifpublic 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.gifpublic 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.gifString 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的文章您可以访问《Castle 开发系列文章》。

 














本文转自lihuijun51CTO博客,原文链接:http://blog.51cto.com/terrylee/67692 ,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
借助阿里云ECS实现传统.NET应用容器化(上)
我们都知道.NET Core应用可以跑在Docker上,那.NET Framework 4.x应用呢?借助阿里云ECS主机(Windows Server 2019 with Container版本),一切变得So Easy!
414 0
Spring IOC 容器源码分析
原文出处:https://javadoop.com/post/spring-ioc Spring 最重要的概念是 IOC 和 AOP,本篇文章其实就是要带领大家来分析下 Spring 的 IOC 容器。
791 0
【云栖号案例 | 教育&科研机构】百家云借助“容器+神龙”三天内实现数十倍扩容
受疫情影响百家云的业务量短时间内增长了数十倍,急需扩容。上云后提供弹性计算的空间与敏捷安全的扩容能力、稳定的服务与优异性能。
3110 0
遍历vector容器的效率问题
 今天看到关于vector遍历效率问题,以前遍历的时候却没有关心这些,实为惭愧。自己写了点代码放在vs2012上运行,得到结果和原来的博客上内容不符合。看来应该还有与平台和编译器优化有关。       代码如下: #include "stdafx.h" #include &lt;vector&gt; #include &lt;algorithm&gt; #include &lt;f
1062 0
福利!阿里宣布手淘安卓客户端容器化框架Atlas正式开源
3月13日,手机淘宝安卓客户端容器化框架Atlas正式宣布开源(https://github.com/alibaba/atlas)。Atlas由阿里巴巴移动团队自研,以容器化思路解决大规模团队协作问题,实现并行开发、快速迭代和动态部署,适用于Android 4.x以上系统版本的大小型App开发。
17416 0
使用OpenApi弹性释放和设置云服务器ECS释放
云服务器ECS的一个重要特性就是按需创建资源。您可以在业务高峰期按需弹性的自定义规则进行资源创建,在完成业务计算的时候释放资源。本篇将提供几个Tips帮助您更加容易和自动化的完成云服务器的释放和弹性设置。
20928 0
Maven初探-如何发布到Tomcat容器中
写在开始 上一篇文章中有讲到,Maven初探-如何快速入手一个项目 提到如何发布到Jetty容器中,但是大多数小伙伴们还是倾向于使用Tomcat容器。 配置Tomcat pom.xml配置:
1860 0
+关注
10140
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载