0

ICommand我们目前使用 SimpleInjector 作为我们的 DI 容器,通过使用andIQuery<TResult>ICommandHandler<TCommand>andIQueryHandler<TQuery, TResult>接口来实现命令-查询-分离 (CQS) 模式。

我们还使用装饰器模式来执行面向方面的编程。对于我们的装饰器之一,我们使用 FluentValidation 来执行特定命令或查询的验证逻辑。

使用 SimpleInjector,可以有条件地注册类型。当我们有一个没有相应验证器的命令或查询时,这对我们的 FluentValidation 装饰器很有用。然后我们使用 aNullValidator<T>作为后备,它什么都不做。正是在SimpleInjector 文档中描述了这种场景,对于 FluentValidation 场景看起来像这样:

public class NullValidator<T> : AbstractValidator<T>
{
}
container.RegisterConditional(
    typeof(IValidator<>),
    typeof(NullValidator<>),
    c => !c.Handled); // Applied if no other validator matches

NullValidator<T>是必需的,因为总是应用装饰器并且总是IValidator<T>注入 a 。对于不存在的特定验证器,NullValidator<T>使用 。这是命令的 FluentValidation 装饰器的构造函数:

public FluentValidationCommandHandlerDecorator(
    IValidator<TCommand> validator,
    ICommandHandler<TCommand> decoratee)
    {
        this.validator = validator ?? throw new ArgumentNullException(nameof(validator));
        this.decoratee = decoratee ?? throw new ArgumentNullException(nameof(decoratee));
    }

这工作得很好,但现在我们正在评估删除对 SimpleInjector 的依赖,并结合使用 .NET 依赖注入 ( IServiceCollectionfrom Microsoft.Extensions.DependencyInjection) 和Scrutor来注册我们的ICommandHandler<T>IQueryHandler<TQuery, TResult>实现以及我们的装饰器。

有没有办法在 .NET DI 框架中执行类似的条件注册逻辑或后备机制,如 SimpleInjector 支持?

4

1 回答 1

0

IEnumerable<IValidator<T>>我设法通过在FluentValidationCommandHandlerDecorator装饰器中注入一个而不是单个IValidator<T>实例来解决这个问题。在这种情况下,我根本不需要 aNullValidator<T>并且如果没有可用于特定命令或查询的验证器,则会注入一个空集合。

必须更改 SimpleInjector 以注册IValidator<T>实例集合:

container.Collection.Register(typeof(IValidator<>), assemblies);

Microsoft.Extensions.DependencyInjectionDI 容器支持开箱即用的注入,IEnumerable<IValidator<T>>无需更改注册中的任何内容。

于 2021-10-29T19:14:24.260 回答