Castle Windsor:扫描装配时的条件组件注册

时间:2016-01-07 11:29:49

标签: castle-windsor

使用Castle Windsor注册多个在顶部链接共享一个公共接口的组件,使用以下内容:

container.Register(
    Types.FromAssemblyNamed("MyProject.MyAssembly")
        .BasedOn<IService>()
        .WithServiceAllInterfaces()
        .Configure(c => c.LifeStyle.HybridPerWebRequestTransient())
)

在MyAssembly内的所有组件中,我有以下内容:

public interface IHandler : IService
public class MessageHandler : IHandler
public class CachedMessageHandler : IHandler

在上面的注册过程中,有没有办法根据一些条件值选择两个组件之一(MessageHandler或CachedMessageHandler)?

1 个答案:

答案 0 :(得分:0)

是的。

.BasedOn<IService>()

的简写
.Pick().If(t => typeof(IService).IsAssignableFrom(t))

知道这一点,你就有可能做出有力的事情。只是为了让你知道你能做什么:

1。 可能这就是你想要的。根据一些条件值选择两个组件中的一个:

var shouldUseCache = true; //get this from configuration

//later in container.Register
.Pick().If(t =>
{
    if (shouldUseCache)
    {
        return typeof (IService).IsAssignableFrom(t) && typeof (CachedMessageHandler) == t;
    }
    return typeof (IService).IsAssignableFrom(t) && typeof (MessageHandler) == t;
})

但请注意:

  • 一旦注册了组件,从容器中删除该注册将很难/不可能/反模式
  • 如果您进行&#34;条件注册&#34;,开发人员稍后调试注入可能会很棘手。根据您的具体情况,您可能需要创建 HandlerProvider ,其中包含以下明确方法: .GetCached .GetTransient

2。 您可以选择实施 IService 的所有类型,但不包括那些也实施 IHandler 的类型:

.Pick().If(t => typeof(IService).IsAssignableFrom(t)
                && !typeof(IHandler).IsAssignableFrom(t))

3。 您可以执行命名约定,例如,仅注册实现 IHandler 的所有类型,并以 SuperHandler 结尾:

.Pick().If(t => typeof(IHandler).IsAssignableFrom(t)
                && t.Name.EndsWith("SuperHandler"))