2010-10-28 65 views
0

因此,我一直在努力構建一個解決方案,該解決方案只使用Castle DynamicProxy(版本2.2)和攔截器創建某些組件。一切看起來都很棒,除了在這一切的最後,我意識到我需要用windsor容器註冊這些組件。這是可能的還是我的工作是沒有用的?註冊DynamicProxy動態創建的城堡組件

我會編造2個城堡配置來解釋我的問題。第一個工作,而第二個不工作。

首先配置(這已經工作了一段時間大):

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

    <components> 
    <component 
     id="Factory" 
     service="Foo.IFactory, Foo" 
     type="Foo.Local.LocalFactory, Foo.Local" /> 
    <component 
     id="Loader" 
     service="Foo.Contracts.ILoader, Foo.Contracts" 
     type="Foo.Local.Loader, Foo.Local" 
     factoryId="Factory" factoryCreate="GetLoader" /> 
    </components> 
</castle> 

其次配置(我不知道該放什麼類型的屬性,它並沒有它的工作):

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

    <components> 
    <component 
     id="Factory" 
     service="Foo.IFactory, Foo" 
     type="Foo.Remote.RemoteFactory, Foo.Remote" /> 
    <component 
     id="Loader" 
     service="Foo.Contracts.ILoader, Foo.Contracts" 
     type="I DUNNO, WHAT'S THE TYPE?" 
     factoryId="Factory" factoryCreate="GetLoader" /> 
    </components> 
</castle> 

所以我製造的配置註冊工廠設施,然後我註冊一個工廠,然後註冊我的「ILoader」組件。 「LocalFactory」爲ILoader組件創建實際類型,而「RemoteFactory」使用動態代理創建ILoader組件,創建無目標的代理。即,我使用ProxyGenerator.CreateInterfaceProxyWithoutTarget方法,因此沒有基礎類。

那麼,根據第二個配置註冊組件有沒有希望?

編輯: 不幸的是,使用流利的配置API目前不是一種選擇。所以爲了縮小我的問題,是否可以使用XML配置來實現這一點?

+0

您是否嘗試過用流利的(基於代碼)註冊機制爲您製作的場景?我會給出一個答案,使用「UsingFactoryMethod」擴展來調用創建ILoader接口的DynamicProxy實現者的代碼。使用流暢的註冊API,您無需在註冊工廠構建的服務時指定具體類型。 – 2010-10-28 16:19:50

回答

2

我相信這可以通過Fluent Registration API和「UsingFactoryMethod」機制來實現。我試圖在下面的測試案例中複製你的製作場景。

UPDATE

這實際上可能與XML配置爲好。訣竅就是將接口本身列爲配置中的「類型」(或者等同於只指定「類型」,因爲如果未明確提供,「服務」將被設置爲「類型」)。我已經更新了下面的測試用例,以包含一個使用xml配置實現所需結果的「TestXml」測試。 「TestFluent」測試使用流暢的註冊API來實現它。僅供參考,我在這裏使用Castle Windsor 2.0,因爲我猜這就是你正在使用的。

using Castle.DynamicProxy; 
using Castle.Facilities.FactorySupport; 
using Castle.MicroKernel.Registration; 
using Castle.Windsor; 
using NUnit.Framework; 

namespace CastleTests 
{ 
    public interface ILoader 
    { 
     void Load(); 
    } 

    public interface ILoaderFactory 
    { 
     ILoader GetLoader(); 
    } 

    public class LoaderFactory : ILoaderFactory 
    { 
     public ILoader GetLoader() 
     { 
      return GetLoaderStatic(); 
     } 

     public static ILoader GetLoaderStatic() 
     { 
      return (ILoader) new ProxyGenerator().CreateInterfaceProxyWithoutTarget(typeof (ILoader)); 
     } 
    } 

    [TestFixture] 
    public class DynamicFactoryTests 
    { 
     [Test] 
     public void TestFluent() 
     { 
      using (var container = new WindsorContainer()) 
      { 
       container.AddFacility<FactorySupportFacility>(); 
       container.Register(
        Component.For<ILoader>().UsingFactoryMethod(() => LoaderFactory.GetLoaderStatic()) 
        ); 
       var loader = container.Resolve<ILoader>(); 
       Assert.That(loader.GetType().FullName, Is.EqualTo("Castle.Proxies.ILoaderProxy")); 
      } 
     } 

     [Test] 
     public void TestXml() 
     { 
      using (var container = new WindsorContainer("factory.xml")) 
      { 
       var loader = container.Resolve<ILoader>(); 
       Assert.That(loader.GetType().FullName, Is.EqualTo("Castle.Proxies.ILoaderProxy")); 
      } 
     } 
    } 
} 

「factory.xml」的內容正是如此:

<castle> 
    <facilities> 
    <facility 
     id="factory.support" 
     type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" /> 
    </facilities> 
    <components> 
    <component 
     id="foo" 
     service="CastleTests.ILoaderFactory, CastleTests" 
     type="CastleTests.LoaderFactory, CastleTests" /> 
    <component 
     id="bar" 
     type="CastleTests.ILoader, CastleTests" 
     factoryId="foo" factoryCreate="GetLoader" /> 
    </components> 
</castle> 
+0

謝謝,這是有用的信息,但不幸的是,使用流利的註冊目前不適合我。 – joniba 2010-10-28 17:02:50

+0

我又看了一遍,想通過xml如何做到這一點 - 見我更新的答案。 – 2010-10-28 17:31:03

+0

謝謝先生,那看起來不錯。所以非常簡單!星期天我回去工作時我會檢查它。 – joniba 2010-10-28 19:51:59