FluentValidation验证器和简单注入器,其中验证器作为数组注入

时间:2016-04-30 23:45:12

标签: c# simple-injector

我的FluentValidation验证程序使用Simple Injector时遇到了一些问题。

我有一个装饰器,其构造函数为:

public CommandHandlerValidationDecorator(
    IRequestHandler<TRequest, TRepsonse> innerHandler, 
    IValidator<TRequest>[] validators)
{
    _decoratedHandler = innerHandler;
    _validators = validators;
}

问题在于第二个参数IValidator<TRequest>[] validators

在我收到的错误消息的指导下,我按照以下方式进行了配置:

container.Register(typeof(FluentValidation.IValidator<>), new[] { assembly });
container.RegisterCollection(typeof(FluentValidation.IValidator<>), new[] { assembly });
container.Register(typeof(IRequestHandler<,>),new [] { assembly });
container.RegisterDecorator(typeof(IRequestHandler<,>), 
    typeof(CommandHandlerValidationDecorator<,>));

这很好,直到我将生命周期范围更改为每个网络请求:

container.Register(typeof(FluentValidation.IValidator<>), new[] { assembly }, 
    Lifestyle.Scoped);
container.RegisterCollection(typeof(FluentValidation.IValidator<>), new[] { assembly });
container.Register(typeof(IRequestHandler<,>),new [] { assembly }, Lifestyle.Scoped);
container.RegisterDecorator(typeof(IRequestHandler<,>), 
    typeof(CommandHandlerValidationDecorator<,>), Lifestyle.Scoped);

看起来你不能将RegisterCollection的范围扩展到每个web请求,这会成为一个问题,因为生活方式不匹配会引发异常:

  

其他信息:遇到生活方式不匹配。 CommandHandlerValidationDecorator(Web请求)依赖于IValidator [](瞬态)。生活方式不匹配会导致应用程序出现并发错误。请参阅https://simpleinjector.org/dialm以了解此问题以及解决方法。

也许我试图强迫一些不好的做法?

1 个答案:

答案 0 :(得分:3)

您在文档中描述的内容为here

  

Simple Injector保留从注入的IEnumerable<T>ICollection<T>IList<T>IReadOnlyCollection<T>IReadOnlyList<T>实例返回的实例的生活方式。实际上,您不应该将注入的IEnumerable<T>视为实例的集合;你应该把它看作一个实例流。 Simple Injector将始终注入对同一个流的引用(IEnumerable<T>ICollection<T>本身是单个),每次迭代IEnumerable<T>时,对于每个单独的组件,都会询问容器根据该组件的生活方式解析实例。

     

警告:与集合抽象相反,数组被注册为瞬态。数组是可变类型;消费者可以更改数组的内容。共享数组(通过使其成为单例)可能会导致应用程序的不相关部分因阵列更改而失败。由于数组是具体类型,因此它不能用作流,从而导致数组中的元素获取消耗组件的生命周期。当数组未注册为瞬态时,这可能会导致lifestyle mismatches

所以你有两个选择:

  1. 使阵列的消费者也成为瞬态,或
  2. 将参数的参数从数组更改为IEnumerable<T>ICollection<T>IList<T>IReadOnlyCollection<T>IReadOnlyList<T>