zoukankan      html  css  js  c++  java
  • 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 开发系列文章》。

  • 相关阅读:
    [动图演示]Redis 持久化 RDB/AOF 详解与实践
    挑战10个最难的Java面试题(附答案)【上】
    Python使用psutil模块,做你的电脑管家
    在线工具 正则表达式
    [USACO09JAN]Earthquake Damage
    [USACO09MAR]Moon Mooing
    [HNOI2005]汤姆的游戏
    [SDOI2010]大陆争霸
    [USACO08NOV]Cheering up the Cow
    [USACO08NOV]lites
  • 原文地址:https://www.cnblogs.com/lvfeilong/p/Castle-2.html
Copyright © 2011-2022 走看看