开发者

Sharing instance of class between other classes in Castle Windsor

I'm trying to figure out the best way to share an instance of a class between two other classes that depend on it.

Say I have these classes:

class A
{
    public A(B b, C c) {}
}

class B
{
    public B(IDFactory factory) {}
}

class C
{
    public C(IDFactory factory) {}
}

interface IDFactory
{
    D GetD();
}

class D {}

And for each instance of A, I want the D used by c and d to be a single instance of D. When I create a new instance of A (say using a factory), I want c and d to share a new instance of D.

So far I've figured that using a custom lifestyle that uses a context (using this cool library) might be the best approach. So I would do something like this:

WindsorContainer container = new WindsorContainer();
[.. standard container registration stuff ..]
container.Register(Component.For<D>().LifeStyle.Custom<ContextualLifestyle>());

IAFactory factory = container.Resolve<IAFactory>();
using (new ContainerContext(container))
{
    A a = factory.GetA();
}

Now the problem I have with this is that I have to define the context at the point where I use the factory. Ideally this concept that D is semi-transient and should have a single instance per instance of A would be configured in the container when I register all my types. Another issue is that the context needs an instance of the container itself, which goes against the Three Container Calls pattern.

Can anyone suggest a better way of setting this kind of thing up, either using Windsor or with a better architecture. Also bearing in mind that D might be quite deep in the class heirarchy i.e. A -> B -> C -> E -> F -> G -> D and I want to avoid passing D all the way down the tree开发者_JS百科.


If you want to share the same instance of D between b and c dependencies of A, then this should be enough:

class A
{
    public A(B b, C c) { }
}

class B
{
    public B(D d) { }
}

class C
{
    public C(D d) { }
}


...
container.Register(Component.For<D>().LifeStyle.Custom<ContextualLifestyle>());
A a = container.Resolve<A>();

If your IAFactory is implemented using container.Resolve you can use that instead of a direct call.

Also, if you are only resolving one "top level" component, you can omit the explicit creation of the context.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜