程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Castle IOC容器實踐之FactorySupport Facility

Castle IOC容器實踐之FactorySupport Facility

編輯:關於.NET

它使用了以下兩種處理策略:

1.使用訪問器來訪問組件的實例

2.使用靜態方法或者實例方式來訪問組件的實例

主要內容

1.概述

2.為什麼需要FactorySupport Facility

3.如何使用

4.常見的配置示例

5.實現原理淺析

一.概述

FactorySupport Facility允許我們使用已經存在的工廠來創建組件的實例,可以把已經存在的對象模型加入到容器中,以便它能夠使用自動裝配。它使用了以下兩種處理策略:

1.通過訪問器來訪問組件的實例

2.通過靜態方法或者實例方式來訪問組件的實例

二.為什麼需要FactorySupport Facility

為了回答這個問題,我們先來看一個簡單的使用工廠的例子,如下代碼所示:

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的實例,簡單一點會這樣去寫:

public class App
{
  static void Main()
  {
    MyFactory factory = new MyFactory();
    IComponent comp = factory.Create();
    comp.Display();
  }
}

正如你所看到的,在程序中使用new關鍵字創建了一個工廠的實例,再由工廠得到組件的實例。現在我們看使用FactorySupport Facility後帶來了什麼好處。工廠和組件的代碼不變,仍然是:

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();
  }
}
配置文件,現在你可以不用理解怎麼去配置,後面會講到。

<?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>

使用組件的實例

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到容器中,可以使用代碼加入也可以使用配置文件。

使用代碼加入:

IWindsorContainer container = new WindsorContainer("../../Basic.xml");
container.AddFacility("factorysupport",new Castle.Facilities.FactorySupport.FactorySupportFacility());

使用配置文件:

<facilities>
  <facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
</facilities>

2.加入組件時指定使用的是哪種方式

如果使用訪問器只需要指定訪問器的名稱就可以了:

<component id="accessor.comp"
  type="Castle.Facilities.FactorySupport.Tests.Components.SingletonWithAccessor, Castle.Facilities.FactorySupport.Tests"
  instance-accessor="Instance">
</component>

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

<component id="mycomp"
      type="Castle.Facilities.FactorySupport.Tests.Components.MyComp, Castle.Facilities.FactorySupport.Tests"
      factoryId="mycompfactory" factoryCreate="Create">
</component>

四.常見的配置示例

這是一些常見的配置示例,來自於Castle自帶的測試代碼中。

1.訪問器配置示例

有這樣一個單件類

public class SingletonWithAccessor
{
  private static readonly SingletonWithAccessor instance = new SingletonWithAccessor();
  private SingletonWithAccessor()
  {
  }
  public static SingletonWithAccessor Instance
  {
    get { return instance; }
  }
}
配置文件如下:

<?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.普通工廠配置示例

組件類和工廠類如下

public class MyComp
{
  public MyComp()
  {
  }
}
public class MyCompFactory
{
  public MyComp Create()
  {
    return new MyComp();
  }
}

配置文件如下:

<?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.帶參工廠配置示例

組件類和工廠類如下:

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);
  }
}

配置文件如下:

<?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.使用自動裝配工廠配置示例

組件類和工廠類如下:

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);
  }
}

配置文件如下:

<?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。

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 開發系列文章》。

PDF版本下載

示例代碼下載

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved