2010-10-21 23 views
2

當試圖註冊依賴於其實現「裝飾」相同服務接口的服務的可啓動組件時,Castle無法解析可啓動組件,聲稱依賴關係無法解決。奇怪的是,明確解決可啓動組件的工作如預期。我已經在Castle Windsor 2.5和2.5.1中看到過這種行爲。請參閱下面的NUnit的測試用例:Castle Windsor:可啓動設施和「裝飾者模式」依賴性的錯誤

UPDATE

我發現我可以得到啓動的工作機制,但我需要的IFoo的實施者的登記分爲單獨container.Register ()從可啓動組件的註冊中調用。 IFoo註冊必須首先進行。更有意思的是,如果我使用IWindsorInstaller來安裝組件,這可以工作而不是。請參閱額外的測試案例如下:

UPDATE

在一個單獨的安裝程序進行安裝的IFoo的實施者,在以container.Install單獨調用()的作品。通過在params []列表中將其包含的IWindsorInstaller安裝到containerInstall()的單個調用來安裝可啓動組件,不是的工作,但將其安裝在對container.Install()的單獨調用中工作。我已經鞏固所有測試用例到下面的代碼片段:修正了HEAD

using System; 
using Castle.Facilities.Startable; 
using Castle.MicroKernel.Registration; 
using Castle.MicroKernel.SubSystems.Configuration; 
using Castle.Windsor; 
using NUnit.Framework; 

namespace Tests 
{ 
    [TestFixture] 
    public class TestProblemsWithStartableAndDecorators 
    { 
     /// <summary> 
     /// This test passes with the following output to the console: 
     /// 
     /// foo decorator 
     ///  typeof decorated : Foo 
     /// startable constructor 
     ///  typeof foo : FooDecorator 
     /// 
     /// </summary> 
     [Test] 
     public void TestUsingResolve() 
     { 
      using (var container = new WindsorContainer()) 
      { 
       container.AddFacility<StartableFacility>(f => f.DeferredStart()); 
       container.Register(
        Component.For<IFoo>().ImplementedBy<FooDecorator>(), 
        Component.For<IFoo>().ImplementedBy<Foo>(), 
        Component.For<IGetStarted>().ImplementedBy<GetStarted>() 
        ); 
       container.Resolve<IGetStarted>(); 
      } 
     } 

     /// <summary> 
     /// This test should pass with the same output as the above test. 
     /// However, it fails with the following exeption: 
     /// 
     /// Castle.MicroKernel.Handlers.HandlerException : Can't create component 'Tests.TestProblemsWithStartableAndDecorators+FooDecorator' as it has dependencies to be satisfied. 
     /// Tests.TestProblemsWithStartableAndDecorators+FooDecorator is waiting for the following dependencies: 
     /// 
     /// Services: 
     /// - Tests.TestProblemsWithStartableAndDecorators+IFoo. 
     /// A dependency cannot be satisfied by itself, did you forget to add a parameter name to differentiate between the two dependencies? 
     /// 
     /// Tests.TestProblemsWithStartableAndDecorators+foo is registered and is matching the required service, but cannot be resolved. 
     /// </summary> 
     [Test] 
     public void TestUsingStartable() 
     { 
      using (var container = new WindsorContainer()) 
      { 
       container.AddFacility<StartableFacility>(f => f.DeferredStart()); 
       container.Register(
        Component.For<IFoo>().ImplementedBy<FooDecorator>(), 
        Component.For<IFoo>().ImplementedBy<Foo>(), 
        Component.For<IGetStarted>().ImplementedBy<GetStarted>().Start() 
        ); 
      } 
     } 

     public interface IFoo 
     { 
     } 

     public class Foo : IFoo 
     { 
     } 

     public class FooDecorator : IFoo 
     { 
      public FooDecorator(IFoo decorated) 
      { 
       Console.WriteLine("foo decorator"); 
       Console.WriteLine(" typeof decorated : " + decorated.GetType().Name); 
      } 
     } 

     public interface IGetStarted 
     { 
     } 

     public class GetStarted : IGetStarted 
     { 
      public GetStarted(IFoo foo) 
      { 
       Console.WriteLine("startable constructor"); 
       Console.WriteLine(" typeof foo : " + foo.GetType().Name); 
      } 
     } 

     // works 
     [Test] 
     public void TestUsingStartableWithSeparateRegistrations() 
     { 
      using (var container = new WindsorContainer()) 
      { 
       container.AddFacility<StartableFacility>(f => f.DeferredStart()); 
       container.Register(Component.For<IFoo>().ImplementedBy<FooDecorator>(), 
            Component.For<IFoo>().ImplementedBy<Foo>()); 
       container.Register(Component.For<IGetStarted>().ImplementedBy<GetStarted>().Start()); 
      } 
     } 

     // fails 
     [Test] 
     public void TestUsingStartableWithSeparateRegistrationsRegisteringStartableFirst() 
     { 
      using (var container = new WindsorContainer()) 
      { 
       container.AddFacility<StartableFacility>(f => f.DeferredStart()); 
       container.Register(Component.For<IGetStarted>().ImplementedBy<GetStarted>().Start()); 
       container.Register(Component.For<IFoo>().ImplementedBy<FooDecorator>(), 
            Component.For<IFoo>().ImplementedBy<Foo>()); 
      } 
     } 

     // fails 
     [Test] 
     public void TestUsingStartableWithInstaller() 
     { 
      using (var container = new WindsorContainer()) 
      { 
       container.AddFacility<StartableFacility>(f => f.DeferredStart()); 
       container.Install(new TestInstaller()); 
      } 
     } 

     public class TestInstaller : IWindsorInstaller 
     { 
      public void Install(IWindsorContainer container, 
           IConfigurationStore store) 
      { 
       container.Register(Component.For<IFoo>().ImplementedBy<FooDecorator>(), 
            Component.For<IFoo>().ImplementedBy<Foo>()); 
       container.Register(Component.For<IGetStarted>().ImplementedBy<GetStarted>().Start()); 
      } 
     } 

     // works 
     [Test] 
     public void TestUsingStartableWithSeparateFooInstaller() 
     { 
      using (var container = new WindsorContainer()) 
      { 
       container.AddFacility<StartableFacility>(f => f.DeferredStart()); 
       container.Install(new FooInstaller()); 
       container.Register(Component.For<IGetStarted>().ImplementedBy<GetStarted>().Start()); 
      } 
     } 

     // fails 
     [Test] 
     public void TestUsingStartableWithSeparateInstallers() 
     { 
      using (var container = new WindsorContainer()) 
      { 
       container.AddFacility<StartableFacility>(f => f.DeferredStart()); 
       container.Install(new FooInstaller(), new StartableInstaller()); 
      } 
     } 

     // works 
     [Test] 
     public void TestUsingStartableWithSeparateCallsToInstall() 
     { 
      using (var container = new WindsorContainer()) 
      { 
       container.AddFacility<StartableFacility>(f => f.DeferredStart()); 
       container.Install(new FooInstaller()); 
       container.Install(new StartableInstaller()); 
      } 
     } 

     public class FooInstaller : IWindsorInstaller 
     { 
      public void Install(IWindsorContainer container, 
           IConfigurationStore store) 
      { 
       container.Register(Component.For<IFoo>().ImplementedBy<FooDecorator>(), 
            Component.For<IFoo>().ImplementedBy<Foo>()); 
      } 
     } 

     public class StartableInstaller : IWindsorInstaller 
     { 
      public void Install(IWindsorContainer container, 
           IConfigurationStore store) 
      { 
       container.Register(Component.For<IGetStarted>().ImplementedBy<GetStarted>().Start()); 
      } 
     } 
    } 
} 
+0

+1用於創建正確的測試用例! – 2010-10-21 17:50:47

回答

1

。將成爲2.5.2版本的一部分。供將來參考,here's the bug report

+0

謝謝 - 我已確認最新版本修復了這些測試。然而,升級使我的另一個測試中斷了。破損與您爲這個可啓動設施問題所做的更改無關。我已經在這裏發佈了新的問題:http://issues.castleproject.org/issue/IOC-239和這裏http://stackoverflow.com/questions/4016638/castle-windsor-arrayresolver-attempts-to-instantiate-一個-無法解決的陣列,依賴 – 2010-10-25 16:22:01

相關問題