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

C# FluentValidation验证器和简单注入器,其中验证器作为数组注入,c#,simple-injector,C#,Simple Injector,让我的FluentValidation验证器使用Simple Injector时遇到一些问题 我有一个具有以下构造的装饰师: public CommandHandlerValidationDecorator( IRequestHandler<TRequest, TRepsonse> innerHandler, IValidator<TRequest>[] validators) { _decoratedHandler = innerHandler

让我的FluentValidation验证器使用Simple Injector时遇到一些问题

我有一个具有以下构造的装饰师:

public CommandHandlerValidationDecorator(
    IRequestHandler<TRequest, TRepsonse> innerHandler, 
    IValidator<TRequest>[] validators)
{
    _decoratedHandler = innerHandler;
    _validators = validators;
}
public命令HandlerValidationDecorator(
IRequestHandler innerHandler,
IValidator[]验证器)
{
_decoratedHandler=innerHandler;
_验证器=验证器;
}
问题在于第二个参数,
IValidator[]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});
RegisterCollection(typeof(FluentValidation.IValidator),new[]{assembly});
Register(typeof(IRequestHandler),new[]{assembly});
容器.RegisterDecorator(typeof(IRequestHandler),
类型(CommandHandlerValidationDecorator));
这很好,直到我将生存期范围更改为每个web请求:

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);
container.Register(typeof(FluentValidation.IValidator),new[]{assembly},
生活方式(范围);
RegisterCollection(typeof(FluentValidation.IValidator),new[]{assembly});
Register(typeof(IRequestHandler),new[]{assembly},lifesture.Scoped);
容器.RegisterDecorator(typeof(IRequestHandler),
typeof(CommandHandlerValidationDecorator),lifesture.Scoped);
看起来您无法将RegisterCollection的作用域设置为每个web请求,这成为一个问题,因为由于生活方式不匹配而引发异常:

附加信息:生活方式不匹配。CommandHandlerValidationDecorator(Web请求)依赖于IValidator[](瞬态)。生活方式不匹配可能导致应用程序中出现并发错误。请参阅以了解此问题以及如何解决此问题


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

文档中描述了您看到的情况:

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

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

所以你有两个选择:

  • 使阵列的使用者也成为瞬态的,或者
  • 将参数的参数从数组更改为
    IEnumerable
    ICollection
    IList
    IReadOnlyCollection
    IReadOnlyList

  • 将构造函数参数更改为
    IEnumarable
    ,您就没事了。@Steven感谢您快速给出的答案!谢谢你,史蒂文。我一直在看文件。我没有抓住那一点。谢谢你在这里解释。这也是很好的文档。