每个Resolve城堡自定义生活方式

时间:2011-03-07 23:36:58

标签: 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>());

我希望每次调用Resolve 时,都会在所有依赖项 中使用相同的LowLevelComponent实例。

所以,在这些电话之后:

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 :(得分:0)

您一定听说有人建议您只为您的应用入口点(主要,控制器等)调用Resolve 一次。 Castle文档对此有很好的guidelines

答案 1 :(得分:0)

根据毛里西奥的链接,我让它使用工厂:

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

不确定这是一个好的黑客还是一个丑陋的黑客,但是效果非常好。