2010-10-21 22 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

相关问题