Круговые «интерфейсы» зависимостей и Castle-Windsor - PullRequest
3 голосов
/ 17 марта 2010

У меня есть компоненты:

public interface IFoo
{ }

public interface IBar
{ }

public class Foo : IFoo
{
    public IBar Bar { get; set; }
}

public class Bar : IBar
{
    public IFoo Foo { get; set; }
}

У меня есть конфигурация Касл-Виндзор:

Container.AddComponent("IFoo", typeof (IFoo), typeof (Foo));
Container.AddComponent("IBar", typeof (IBar), typeof (Bar));

и провал модульного теста:

[Test]
public void FooBarTest()
{
    var container = ObjFactory.Container;

    var foo = container.Resolve<IFoo>();
    var bar = container.Resolve<IBar>();

    Assert.IsNotNull(((Foo) foo).Bar);
    Assert.IsNotNull(((Bar) bar).Foo);
}

Сбой из-за циклической зависимости "foo" .Bar или "bar" .oo имеет значение null. Как настроить Castle для правильной инициализации обоих компонентов?

Я могу правильно инициализировать оба компонента вручную:

[Test]
public void FooBarTManualest()
{
    var fooObj = new Foo();
    var barObj = new Bar();

    fooObj.Bar = barObj;
    barObj.Foo = fooObj;

    var foo = (IFoo) fooObj;
    var bar = (IBar) barObj;

    Assert.IsNotNull(((Foo)foo).Bar);
    Assert.IsNotNull(((Bar)bar).Foo);
}

.. и это работает, проходит. Как сделать такую ​​настройку с помощью Castle Windsor?

1 Ответ

12 голосов
/ 17 марта 2010

Обычно такие циклические ссылки являются плохой идеей ™, и Виндзор не разрешает их, поэтому эту часть вам придется выполнить вручную:

        var container = new WindsorContainer();
        container.Register(Component.For<IFoo>().ImplementedBy<Foo>()
                            .OnCreate((k, f) =>
                                        {
                                            var other = k.Resolve<IBar>() as Bar;
                                            ((Foo)f).Bar = other;
                                            other.Foo = f;
                                        }),
                           Component.For<IBar>().ImplementedBy<Bar>());
        var foo = container.Resolve<IFoo>() as Foo;
        var bar = container.Resolve<IBar>() as Bar;

        Debug.Assert(bar.Foo != null);
        Debug.Assert(foo.Bar != null);
        Debug.Assert((foo.Bar as Bar).Foo == foo);
        Debug.Assert((bar.Foo as Foo).Bar == bar);

Тем не менее, это довольно редко, чтобы действительно нуждаться в этой округлости. Вы можете пересмотреть свой дизайн.

...