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

Mar*_*ski 5 castle-windsor

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

使用此约定注册:

container.Register(
    AllTypes.FromThisAssembly().Pick()
        .WithService.DefaultInterface())
Run Code Online (Sandbox Code Playgroud)

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

IFoo = Foo
IBar = FirstBar
IBar = SecondBar
Run Code Online (Sandbox Code Playgroud)

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

container.Register(
    AllTypes.FromThisAssembly().Pick()
        .WithService.DefaultInterface()
        .For<IBar>().Select<SecondBar>())
Run Code Online (Sandbox Code Playgroud)

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

Krz*_*mic 5

收紧你的习俗.这显然是广泛的.

container.Register(
    AllTypes.FromThisAssembly()
        .Where(t => t.Namespace != "Acme.Tests")
        .WithService.DefaultInterface())
Run Code Online (Sandbox Code Playgroud)


Mar*_*ski 3

这就是完成工作的原因:

\n\n
container.Register(\n    AllTypes.FromThisAssembly().Pick()\n        .WithService.DefaultInterface())\n        .ConfigureFor<IBar>(c => \n            c.If((k, m) => m.Implementation == typeof(SecondBar)));\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

为此,我们继续创建了一些不错的小扩展方法:

\n\n
public static BasedOnDescriptor Select<TService, TImpl>(this BasedOnDescriptor desc)\n{\n    return desc.ConfigureFor<TService>(c => c.If((k, m) => m.Implementation == typeof(TImpl)));\n}\n\npublic static BasedOnDescriptor Ignore<TService>(this BasedOnDescriptor desc)\n{\n    return desc.ConfigureFor<TService>(c => c.If((k, m) => false));\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
container.Register(\n    AllTypes.FromThisAssembly().Pick()\n        .WithService.DefaultInterface())\n        .Select<IBar, SecondBar>()\n        .Ignore<ISomeService>()\n
Run Code Online (Sandbox Code Playgroud)\n\n

总而言之,这效果很好。我相信这两种方法可能在 Castle.Windsor 中。@Krzysztof Ko\xc5\xbamic:我在哪里提交补丁?:)

\n