当试图注册依赖于其实现“装饰”相同服务接口的服务的可启动组件时,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());
}
}
}
}
+1用于创建正确的测试用例! – 2010-10-21 17:50:47