我正在使用MediatR构建管道。我添加了一个旨在验证查询和命令的简单行为:public class ValidationBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : IRequest<Result> where TResponse : Result{ private readonly IEnumerable<IValidator<TRequest>> _validators; public ValidationBehavior(IEnumerable<IValidator<TRequest>> validators) { _validators = validators ?? Enumerable.Empty<IValidator<TRequest>>(); } public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next) { (...) }}目前,我的大多数查询都继承自PaginatedQuery。public abstract class PaginatedQuery : IQuery{ public int Offset { get; set; } = 0; public int Limit { get; set; } = 25;}例:public class GetCountriesQuery : PaginatedQuery{ public GetCountriesQuery(PaginatedInput input) { Limit = input.Limit; Offset = input.Offset; }}为了确保用户不会发送无效的偏移/限制,我构建了以下验证器:public class PaginatedQueryValidator : AbstractValidator<PaginatedQuery>{ public PaginatedQueryValidator() { RuleFor(p => p.Offset) .GreaterThanOrEqualTo(0) .WithMessage("Offset must be greater or equal to 0"); RuleFor(p => p.Limit) .GreaterThan(0) .WithMessage("Limit must be greater than 0"); }}不幸的是,即使TRequest从PaginatedQuery继承,也不会将该验证器注入到我的ValidationBehavior中。  最后,我将需要为当前的TRequest以及所有母类注入验证器(即:PaginatedQuery)。这是可以实现的吗?注意:要注入验证器,我将扫描所有实现IValidator 的类型(使用Scrutor) services.Scan(x => x.FromAssembliesOf(typeof(Startup)) .AddClasses(c => c.AssignableToAny(typeof(IValidator<>))) .AsImplementedInterfaces() );编辑:我忘了提到我正在使用AutoFac (adsbygoogle = window.adsbygoogle || []).push({}); 最佳答案 当Autofac解析ValidationBehavior<GetCountriesQuery, GetCountriesResponse>时,您希望它解析IValidator<GetCountriesQuery>,而只有IValidator<PaginatedQuery>被注册,并且IValidator<PaginatedQuery>不可分配给IValidator<GetCountriesQuery>您可以尝试使用以下C#语句IValidator<GetCountriesQuery> i = (IValidator<PaginatedQuery>)null;C#编译器将为您显示此错误消息  错误CS0266:无法将类型IValidator<PaginatedQuery>隐式转换为IValidator<GetCountriesQuery>。存在显式转换(您是否缺少演员表?)为了使它起作用,C#4为泛型类型参数引入了协方差和逆方差。它允许将IValidator<Base>强制转换为IValidator<Derived>或相反。有关更多信息,请参见MSDN上的covariance and contravariance。在您的情况下,您需要使用in关键字可以声明的方差public interface IValidator<in TRequest> { }为了使Autofac与协变一起工作,您必须注册一个ContravariantRegistrationSource注册源:builder.RegisterSource(new ContravariantRegistrationSource()); (adsbygoogle = window.adsbygoogle || []).push({});
10-07 18:04