Castle Windsor:使用约定注册以及特定实现

时间:2011-01-07 15:22:01

标签: castle-windsor

假设由FirstBar和SecondBar实现的Foo和IBar实现了IFoo。

使用此约定注册:

container.Register(
    AllTypes.FromThisAssembly().Pick()
        .WithService.DefaultInterface())

我们在容器中有三个条目:

IFoo = Foo
IBar = FirstBar
IBar = SecondBar

现在,我们如何调整此注册以告知容器对于IBar我们只想注册SecondBar?排序:

container.Register(
    AllTypes.FromThisAssembly().Pick()
        .WithService.DefaultInterface()
        .For<IBar>().Select<SecondBar>())

使用案例:我们的应用程序中有很多服务都是按惯例注册的。然而,一些服务接口具有两个或更多个实现(例如,实际实现,虚假实现和测试实现)。公约注册将在同一界面下注册它们,在解析界面时,我们将获得第一个实现(以非确定性顺序)。我们希望能够在注册时为这些服务选择一个特定的实现。我们怎么能这样做?

2 个答案:

答案 0 :(得分:5)

收紧你的惯例。这显然是广泛的。

container.Register(
    AllTypes.FromThisAssembly()
        .Where(t => t.Namespace != "Acme.Tests")
        .WithService.DefaultInterface())

答案 1 :(得分:3)

这就是完成工作的原因:

container.Register(
    AllTypes.FromThisAssembly().Pick()
        .WithService.DefaultInterface())
        .ConfigureFor<IBar>(c => 
            c.If((k, m) => m.Implementation == typeof(SecondBar)));

这有效地仅为IBar服务注册SecondBar impl。这样,如果给定服务有多个实现,我们可以告诉我们想要的传统扫描器。

我们继续为此目的创建了很好的小扩展方法:

public static BasedOnDescriptor Select<TService, TImpl>(this BasedOnDescriptor desc)
{
    return desc.ConfigureFor<TService>(c => c.If((k, m) => m.Implementation == typeof(TImpl)));
}

public static BasedOnDescriptor Ignore<TService>(this BasedOnDescriptor desc)
{
    return desc.ConfigureFor<TService>(c => c.If((k, m) => false));
}

我们现在可以这样使用它:

container.Register(
    AllTypes.FromThisAssembly().Pick()
        .WithService.DefaultInterface())
        .Select<IBar, SecondBar>()
        .Ignore<ISomeService>()

总而言之,这很有效。我相信这两种方法可以在Castle.Windsor中。 @KrzysztofKoźmic:我在哪里提交补丁? :)