/ / Dependências de 'interfaces' circulares e Castle-Windsor - castle-windsor

Dependências circulares de 'interfaces' e Castle-Windsor - castle-windsor

Eu tenho componentes:

public interface IFoo
{ }

public interface IBar
{ }

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

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

Tenho a configuração Castle-Windsor:

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

e falha no teste de unidade:

[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);
}

Ele falha, devido à dependência circular, "foo" .Bar ou "bar" .Foo é nulo. Como posso configurar o Castle para inicializar ambos os componentes corretamente?

Posso inicializar corretamente os dois componentes manualmente:

[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);
}

.. e funciona, passa. Como fazer essa configuração usando o Castle Windsor?

Respostas:

12 para resposta № 1

Geralmente referências circulares como esta são uma Bad Idea ™ e Windsor não as resolve, então esta parte você teria que fazer manualmente:

        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);

No entanto, é bastante incomum realmente precisar dessa circularidade. Você pode querer revisar seu design.