Autofac Keyed Factory:不同枚举值的相同具体实现

Autofac Keyed Factory: Same Concrete Implementation For Different Enum Values

我想使用 autofac 的内置 IIndex 创建一个字段验证器工厂,它将接受一个枚举值,return 我是一个 IFieldValidator。 我的验证工厂应该 return 基于提供的令牌类型枚举值的 FieldValidator 或 ConditionalFieldValidator 的具体实现。

Service
User
Candidate
Unknown

当令牌类型为 Service 时,我想要 return 一个 ConditionalFieldValidator,当令牌类型为 User, Candidate or Unknown[=16 时,我想要 return 一个 FieldValidator =]

ContainerBuilder 的 Keyed 方法似乎只接受一个参数,这迫使我像这样注册组件:

builder.RegisterType<ConditionalFieldValidator>().Keyed<IFieldValidator>(TokenType.Service);
builder.RegisterType<FieldValidator>().Keyed<IFieldValidator>(TokenType.User);
builder.RegisterType<FieldValidator>().Keyed<IFieldValidator>(TokenType.Candidate);
builder.RegisterType<FieldValidator>().Keyed<IFieldValidator>(TokenType.Unknown);

有没有更好的方法来做到这一点而不重复 FieldValidator 注册?能够将多种令牌类型传递给 Keyed 方法会很好。

编辑

我最终创建了一个包含 Alistair 和 Cyril 答案的扩展方法。

public static ContainerBuilder RegisterTypeKeyed<TConcrete, TAbstract>(this ContainerBuilder containerBuilder, params object[] values)
{
    var registration = containerBuilder.RegisterType<TConcrete>();
        
    foreach(var value in values)
        registration.Keyed<TAbstract>(value);

    return containerBuilder;
}

这使您可以在一行中从您的容器工厂注册您的键控组件。

builder.RegisterTypeKeyed<ConditionalFieldValidator, IFieldValidator>(AuthTokenType.Service);
builder.RegisterTypeKeyed<FieldValidator, IFieldValidator>(AuthTokenType.Candidate, AuthTokenType.Unknown, AuthTokenType.User);

您应该能够将多个 Keyed 调用叠加到注册上(就像您可以使用 As<T> 一样),如下所示:

builder.RegisterType<FieldValidator>().Keyed<IFieldValidator>(TokenType.User)
                                      .Keyed<IFieldValidator>(TokenType.Candidate)
                                      .Keyed<IFieldValidator>(TokenType.Unknown);

保持FieldValidator组件的相同注册(包括任何实例共享行为),但注册多个服务 .

您可以将一个组件注册到多个服务

builder.RegisterType<FieldValidator>()
       .Keyed<IFieldValidator>(TokenType.User)
       .Keyed<IFieldValidator>(TokenType.Candidate)
       .Keyed<IFieldValidator>(TokenType.Unknown);

这将导致一个注册与多个关联服务。