我正在为我的命令创建验证装饰器,但是我在使用Simple Injector DI容器注册类型时遇到了麻烦。
案例是:
DataAnnotationsCommandValidator<TCommand>
。CreateRefreshTokenCommandValidator
,它实现了ICommandValidator<CreateRefreshTokenCommand>
。根据Simple Injector documentation,在这种情况下应该创建CompositeCommandValidator
。我已经模仿了文档中提到的实现,这意味着我的ValidationCommandHandlerDecorator
仍然可以依赖ICommandValidator<TCommand>
而不是IEnumerable
。
然后是Simple Injector容器的配置。我的配置目前看起来像这样:
_container.RegisterManyForOpenGeneric(
typeof(ICommandValidator<>),
_container.RegisterAll,
typeof (ICommandValidator<>).Assembly);
_container.RegisterAllOpenGeneric(
typeof(ICommandValidator<>),
typeof(DataAnnotationsCommandValidator<>));
_container.RegisterSingleOpenGeneric(
typeof(ICommandValidator<>),
typeof(CompositeCommandValidator<>));
但是,当我调试应用程序时,只有特定的验证器被注入CompositeCommandValidator
(我错过了DataAnnotationsCommandValidator
)。我尝试过几种不同的配置,但无济于事。我应该如何配置Simple Injector以获得正确的行为?
答案 0 :(得分:2)
Simple Injector v4的更新:
// Register validators as sequence
_container.Collection.Register(
typeof(ICommandValidator<>),
typeof (ICommandValidator<>).Assembly);
// Append the data annotations validator as last element to the sequence
_container.Collection.Append(
typeof(ICommandValidator<>),
typeof(DataAnnotationsCommandValidator<>));
// Register the composite that will wrap the sequence.
_container.Register(
typeof(ICommandValidator<>),
typeof(CompositeCommandValidator<>));
Original Simple Injector v2回答:
RegisterManyForOpenGeneric
方法仅扫描程序集以查找给定接口的非泛型实现,因为开放式通用实现通常需要特别小心。这里基本上有两种选择。
选项1:
var types = OpenGenericBatchRegistrationExtensions.GetTypesToRegister(
_container,
typeof (ICommandValidator<>),
AccessibilityOption.PublicTypesOnly,
typeof (ICommandValidator<>).Assembly)
.ToList();
types.Add(typeof(DataAnnotationsValidator<>));
_container.RegisterAll(typeof(ICommandValidator<>), types);
这里我们使用GetTypesToRegister
方法查找所有非泛型实现,我们将open泛型类型附加到此集合,并使用RegisterAll
注册整个集合。
您的第二个选择是将RegisterManyForOpenGeneric
与AppendToCollection
混合:
_container.RegisterManyForOpenGeneric(typeof(ICommandValidator<>),
_container.RegisterAll,
typeof(ICommandValidator<>).Assembly);
// using SimpleInjector.Advanced;
_container.AppendToCollection(typeof(ICommandValidator<>),
typeof(DataAnnotationsValidator<>));