循环“接口”依赖性和Castle-Windsor [英] Circular 'interfaces' dependencies and Castle-Windsor

查看:85
本文介绍了循环“接口”依赖性和Castle-Windsor的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有组件:

public interface IFoo
{ }

public interface IBar
{ }

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

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

我有Castle-Windsor配置:

I've got Castle-Windsor configuration:

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 .Foo为空。
如何配置Castle来正确初始化两个组件?

It fails, because of circular dependency, "foo".Bar or "bar".Foo is null. How can I configure Castle to initialize both components properly?

我可以手动初始化两个组件:

I can initialize properly both components manually:

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

..并且可以通过。
如何使用温莎城堡进行这种配置?

.. and it works, passes. How to make such configuration using Castle Windsor?

推荐答案

一般来说,这样的循环引用是Bad Idea™和Windsor无法解决它们,因此您必须手动执行以下操作:

Generally circular references like this are a Bad Idea™ and Windsor does not resolve them, so this part you'd have to do manually:

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

但是,真正需要这种圆形性并不常见。您可能要修改设计。

However it's is quite uncommon to really need this circularity. You may want to revise your design.

这篇关于循环“接口”依赖性和Castle-Windsor的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆