是否有一种方法可以有条件地注册类型作为.net依赖注入的回退?



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

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

使用SimpleInjector,可以有条件地注册类型。当我们有一个命令或查询没有相应的验证器时,这对我们的FluentValidation装饰器很有用。然后我们使用NullValidator<T>作为不做任何事情的回退。这个场景在SimpleInjector文档中有详细描述,它看起来像这样:
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>总是被注入。对于不存在的特定验证器,使用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依赖注入(IServiceCollectionMicrosoft.Extensions.DependencyInjection)与Scrutor结合来注册我们的ICommandHandler<T>IQueryHandler<TQuery, TResult>实现和我们的装饰器。

有没有办法执行类似的条件注册逻辑或回退机制像SimpleInjector支持在。net DI框架?

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

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

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

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

相关内容

  • 没有找到相关文章

最新更新