根据决心定制城堡生活方式

发布于 2024-10-20 21:33:24 字数 1517 浏览 1 评论 0原文

对于 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

我还将“你做的一切错了,这就是你应该做的”作为回答 :-)

With Castle Windsor, let's say I have the following classes:

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

Registered in the easiest possible way:

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

I'd like to get the same instance of LowLevelComponent used in all dependencies each time I call Resolve.

So, after these calls:

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

The following assertions should be true:

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

I'll also take "you're doing everything wrong, this is what you should do instead" as an answer :-)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雪若未夕 2024-10-27 21:33:24

您一定听说过人们建议只为您的应用入口点(Main、Controller 等)调用 Resolve 一次。 Castle 文档对此有很好的指南

You must've heard people recommending to only call Resolve once for your app entry point (Main, Controller, etc.). Castle documentation has good guidelines on this.

笑咖 2024-10-27 21:33:24

根据 Mauricio 的链接,我使用工厂让它工作:

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

不确定这是一个好的黑客还是一个丑陋的黑客,但它工作得非常好。

Based on Mauricio's link, I got it working using factories:

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

Usage:

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

Not sure if this is a good hack or an ugly one, but it works wonderfully.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文