Castle IOC容器实践之FactorySupport Facility

 PDF版本下载:http://file.ddvip.com/2008_10/1223538519_ddvip_4853.rar示例代码下载:http://file.ddvip.com/2008_10/1223538542_ddvip_4430.rar它使用了以下两种处理策略:

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

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

  主要内容

  1.概述

  2.为什么需要FactorySupport Facility

  3.如何使用

  4.常见的配置示例

  5.实现原理浅析

  一.概述

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

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

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

  二.为什么需要FactorySupport Facility

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

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public interface IComponent
{
  void Display();
}
public class MyComponent : IComponent
{
  public MyComponent()
  { 
  }
  public void Display()
  {
    Console.WriteLine("MyComponent");
  }
}
public class MyFactory
{
  public MyFactory()
  {
  }
  public IComponent Create()
  {
    return new MyComponent();
  }
}

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

双击代码全选
1
2
3
4
5
6
7
8
9
public class App
{
  static void Main()
  {
    MyFactory factory = new MyFactory();
    IComponent comp = factory.Create();
    comp.Display();
  }
}

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

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public interface IComponent
{
  void Display();
}
public class MyComponent : IComponent
{
  public MyComponent()
  {
  }
  public void Display()
  {
    Console.WriteLine("MyComponent");
  }
}
public class MyFactory
{
  public MyFactory()
  {
  }
  public IComponent Create()
  {
    return new MyComponent();
  }
}

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

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <facilities>
    <facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
  </facilities>
  <components>
    <component id="myfactory" type="FactorySupportDemo.MyFactory,FactorySupportDemo" />
    <component id="mycomp" type="FactorySupportDemo.MyComponent,FactorySupportDemo"
      factoryId="myfactory" factoryCreate="Create"></component>
  </components>
</configuration>

  使用组件的实例

双击代码全选
1
2
3
4
5
6
7
8
9
public class App
{
  static void Main()
  {
    IWindsorContainer container = new WindsorContainer("../../Basic.xml");
    IComponent instance = (IComponent) container["mycomp"];
    instance.Display();
  }
}

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

  三.如何使用

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

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

  使用代码加入:

双击代码全选
1
2
IWindsorContainer container = new WindsorContainer("../../Basic.xml");
container.AddFacility("factorysupport",new Castle.Facilities.FactorySupport.FactorySupportFacility());

使用配置文件:

双击代码全选
1
2
3
<facilities>
  <facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
</facilities>

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

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

双击代码全选
1
2
3
4
<component id="accessor.comp"
  type="Castle.Facilities.FactorySupport.Tests.Components.SingletonWithAccessor, Castle.Facilities.FactorySupport.Tests"
  instance-accessor="Instance">
</component>

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

双击代码全选
1
2
3
4
<component id="mycomp"
      type="Castle.Facilities.FactorySupport.Tests.Components.MyComp, Castle.Facilities.FactorySupport.Tests"
      factoryId="mycompfactory" factoryCreate="Create">
</component>

  四.常见的配置示例

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

  1.访问器配置示例

  有这样一个单件类

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
public class SingletonWithAccessor
{
  private static readonly SingletonWithAccessor instance = new SingletonWithAccessor();
  private SingletonWithAccessor()
  {
  }
  public static SingletonWithAccessor Instance
  {
    get { return instance; }
  }
}

配置文件如下:

双击代码全选
1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <facilities>
    <facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
  </facilities>
  <components>
    <component id="accessor.comp" type="Castle.Facilities.FactorySupport.Tests.Components.SingletonWithAccessor, Castle.Facilities.FactorySupport.Tests"
      instance-accessor="Instance"></component>
  </components>
</configuration>

  2.普通工厂配置示例

  组件类和工厂类如下

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
public class MyComp
{
  public MyComp()
  {
  }
}
public class MyCompFactory
{
  public MyComp Create()
  {
    return new MyComp();
  }
}

  配置文件如下:

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <facilities>
    <facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
  </facilities>
  <components>
    <component id="mycompfactory" type="Castle.Facilities.FactorySupport.Tests.Components.MyCompFactory, Castle.Facilities.FactorySupport.Tests" />
    <component id="mycomp" type="Castle.Facilities.FactorySupport.Tests.Components.MyComp, Castle.Facilities.FactorySupport.Tests"
      factoryId="mycompfactory" factoryCreate="Create"></component>
  </components>
</configuration>

  3.带参工厂配置示例

  组件类和工厂类如下:

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class MyComp
{
  private string storeName;
  private IDictionary props;
  internal MyComp()
  {
  }
  internal MyComp(String storeName, IDictionary props)
  {
    this.storeName = storeName;
    this.props = props;
  }
  public string StoreName
  {
    get { return storeName; }
  }
  public IDictionary Props
  {
    get { return props; }
  }
}
public class MyCompFactory2
{
  public MyCompFactory2()
  {
  }
  public MyComp Create(String storeName, IDictionary props)
  {
    return new MyComp(storeName, props);
  }
}

配置文件如下:

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <facilities>
    <facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
  </facilities>
  <components>
    <component id="mycompfactory" type="Castle.Facilities.FactorySupport.Tests.Components.MyCompFactory2, Castle.Facilities.FactorySupport.Tests"></component>
    <component id="mycomp" type="Castle.Facilities.FactorySupport.Tests.Components.MyComp, Castle.Facilities.FactorySupport.Tests"
      factoryId="mycompfactory" factoryCreate="Create">
      <parameters>
        <storeName>MyStore</storeName>
        <props>
          <dictionary>
            <entry key="key1">item1</entry>
            <entry key="key2">item2</entry>
          </dictionary>
        </props>
      </parameters>
    </component>
  </components>
</configuration>

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

  组件类和工厂类如下:

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public interface IMyService
{
}
public class MyComp
{
  private IMyService serv;
  internal MyComp()
  {
  }
  internal MyComp(IMyService serv)
  {
    this.serv = serv;
  }
  public IMyService Service
  {
    get { return serv; }
  }
}
public class MyCompFactory3
{
  public MyCompFactory3()
  {
  }
  public MyComp Create(IMyService serv)
  {
    return new MyComp(serv);
  }
}

  配置文件如下:

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <facilities>
    <facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
  </facilities>
  <components>
    <component id="myserv" service="Castle.Facilities.FactorySupport.Tests.Components.IMyService, Castle.Facilities.FactorySupport.Tests"
      type="Castle.Facilities.FactorySupport.Tests.Components.DefaultMyService, Castle.Facilities.FactorySupport.Tests" />
    <component id="mycompfactory" type="Castle.Facilities.FactorySupport.Tests.Components.MyCompFactory3, Castle.Facilities.FactorySupport.Tests"></component>
    <component id="mycomp" type="Castle.Facilities.FactorySupport.Tests.Components.MyComp, Castle.Facilities.FactorySupport.Tests"
      factoryId="mycompfactory" factoryCreate="Create">
      <!-- parameters is not necessary_u97 ?s it will auto wire --></component>
  </components>
</configuration>

  五.实现原理浅析

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

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
String instanceAccessor = model.Configuration.Attributes["instance-accessor"];
String factoryId = model.Configuration.Attributes["factoryId"];
String factoryCreate = model.Configuration.Attributes["factoryCreate"];
if (instanceAccessor != null)
{
  model.ExtendedProperties.Add( "instance.accessor", instanceAccessor );
  model.CustomComponentActivator = typeof(AccessorActivator);
}
else if (factoryId != null)
{
  model.ExtendedProperties.Add( "factoryId", factoryId );
  model.ExtendedProperties.Add( "factoryCreate", factoryCreate );
  model.CustomComponentActivator = typeof(FactoryActivator);
}

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

上一篇:Oracle 表空间查询与操作方法


下一篇:Oracle 表空间与数据文件