Образ жизни в замке в соответствии с разрешением - PullRequest
2 голосов
/ 08 марта 2011

С Castle Windsor, скажем, у меня есть следующие классы:

public class LowLevelComponent
{
}

public class HighLevelComponent
{
    readonly LowLevelComponent LowLevelComponent;

    public HighLevelComponent(LowLevelComponent lowLevelComponent)
    {
        LowLevelComponent = lowLevelComponent;
    }
}

public class ComponentBeingResolved
{
    readonly LowLevelComponent LowLevelComponent;
    readonly HighLevelComponent HighLevelComponent;

    public ComponentBeingResolved(LowLevelComponent lowLevelComponent,
                                  HighLevelComponent highLevelComponent)
    {
        LowLevelComponent = lowLevelComponent;
        HighLevelComponent = highLevelComponent;
    }
}

Зарегистрировано самым простым способом:

container.Register(Component.For<LowLevelComponent>());
container.Register(Component.For<HighLevelComponent>());
container.Register(Component.For<ComponentBeingResolved>());

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

Итак, после этих звонков:

var instance1 = container.Resolve<ComponentBeingResolved>();
var instance2 = container.Resolve<ComponentBeingResolved>();

Следующие утверждения должны быть верными:

instance1.LowLevelComponent == instance1.HighLevelComponent.LowLevelComponent
instance1.LowLevelComponent != instance2.LowLevelComponent
instance1.HighLevelComponent != instance2.HighLevelComponent

Я также возьму "вы делаете все неправильно, это то, что вы должны сделать вместо этого" в качестве ответа: -)

Ответы [ 2 ]

0 голосов
/ 08 марта 2011

Основываясь на ссылке Маурисио, я начал работать на фабриках:

public interface IComponentFactory
{
    T Get<T>();
}

var container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<LowLevelComponent>()
         .LifeStyle.Custom<ContextualLifestyle>());
container.Register(Component.For<HighLevelComponent>()
         .LifeStyle.Custom<ContextualLifestyle>());
container.Register(Component.For<IComponentFactory>().AsFactory());
//Register the "context-root" component in a child container
var subContainer = new WindsorContainer();
subContainer.Register(Component.For<ComponentBeingResolved>()
            .LifeStyle.Transient);
container.AddChildContainer(subContainer);
container.Register(
    Component.For<ComponentBeingResolved>()
        .LifeStyle.Transient
        //Here's the magic
        .UsingFactoryMethod(
            () =>
                {
                    using (new ContainerContext(container))
                        return subContainer.Resolve<ComponentBeingResolved>();
                }));

Использование:

var factory = container.Resolve<IComponentFactory>();
var instance1 = factory.Get<ComponentBeingResolved>();
var instance2 = factory.Get<ComponentBeingResolved>();

Не уверен, что это хороший или уродливый хак, но он прекрасно работает.

0 голосов
/ 08 марта 2011

Вы, наверное, слышали, как люди рекомендуют вызывать Resolve один раз для точки входа вашего приложения (Main, Controller и т. Д.). В документации замка есть хорошие рекомендации по этому вопросу.

...