Обмен экземпляром класса между другими классами в замке Виндзор - PullRequest
3 голосов
/ 31 января 2011

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

Скажите, у меня есть эти классы:

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 {}

И для каждого экземпляра A я хочу, чтобы D, используемый c и d, был единственным экземпляром D. Когда я создаю новый экземпляр A (скажем, с использованием фабрики), я хочу, чтобы c и d совместно использовали новый экземпляр D.

До сих пор я считал, что наилучшим подходом может быть использование нестандартного образа жизни, в котором используется контекст (с использованием этой классной библиотеки). Поэтому я бы сделал что-то вроде этого:

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

Теперь проблема, с которой я столкнулся, заключается в том, что я должен определить контекст в точке, где я использую фабрику. В идеале это понятие, что D является полупереходным и должен иметь один экземпляр на экземпляр A, будет сконфигурировано в контейнере, когда я зарегистрирую все свои типы. Другая проблема заключается в том, что контексту необходим экземпляр самого контейнера, который идет вразрез с шаблоном Three Container Calls.

Может кто-нибудь предложить лучший способ настройки такого рода вещей, используя Виндзор или с лучшей архитектурой. Также с учетом того, что D может быть достаточно глубоким в иерархии классов, т. Е. A -> B -> C -> E -> F -> G -> D, и я хочу избежать прохождения D полностью вниз по дереву.

1 Ответ

3 голосов
/ 31 января 2011

Если вы хотите разделить один и тот же экземпляр D между зависимостями b и c от A, этого должно быть достаточно:

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

Если ваша IAFactory реализована с использованием container.Resolve, вы можете использовать ее вместопрямого вызова.

Кроме того, если вы разрешаете только один компонент «верхнего уровня», вы можете пропустить явное создание контекста.

...