我正在玩一个测试项目。我正在尝试实现CQS模式,我正在接近完成初始测试。我在尝试解决IQueryValidtor<>
和IQueryHandler<,>
课程时遇到了问题。该方法可以解决它们,但是当我尝试访问具体类中实现的接口方法时,我得到了
“MyProjectsNamespace.GetSiteValidator.Validate(MyProjectsNamespace.Queries.GetSite)”的最佳重载方法匹配包含一些无效参数。
我的代码基于this answer I found。在设计时,一切似乎都在排队,但是运行时间是另一回事。
我在这个问题上包含了我正在处理的所有接口,实现和单元测试。第一次单元测试实际上正在运行。实际上是尝试使用已解析的类的最后两个。我正在使用Autofac进行依赖注入。
public interface IQuery<TResult> {
}
public class GetSite : IQuery<Site> {
public Guid Id { get; set; }
}
public interface IValidator<T> {
Task<List<ValidationResult>> Validate(T command);
}
public class GetSiteValidator : IValidator<GetSite> {
public async Task<List<ValidationResult>> Validate(GetSite command) {
List<ValidationResult> results = new List<ValidationResult>();
if(command == null) {
throw new ArgumentNullException(nameof(command));
}
if(command.Id == Guid.Empty) {
results.Add(new ValidationResult() { FieldName = "Id", Message = "Is empty" });
}
return results;
}
}
public interface IQueryHandler<in TQuery, TResult> where TQuery : IQuery<TResult> {
Task<TResult> Handle(TQuery query);
}
public class GetSiteHandler : IQueryHandler<GetSite, Site> {
public Task<Site> Handle(GetSite query) {
throw new NotImplementedException();
}
}
上面的代码是此问题中使用的所有接口和具体类。下面的代码是我遇到问题的调度员类。
public class QueryDispatcher : IQueryDispatcher {
private readonly IComponentContext _context;
public QueryDispatcher(IComponentContext context) {
_context = context;
}
public async Task<TResult> Dispatch<TResult>(IQuery<TResult> query) {
if (query == null) {
throw new ArgumentNullException(nameof(query), "Query cannot be null");
}
// use dynamic datatype because the tresult is not known at compile time
var validatorType = typeof(IValidator<>).MakeGenericType(query.GetType());
dynamic validator = _context.Resolve(validatorType);
var handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResult));
dynamic handler = _context.Resolve(handlerType);
List<ValidationResult> errors = await validator.Validate(query);
if(errors.Count == 0) {
return await handler.Handle(query);
} else {
// raise failed validation event
throw new ApplicationException("Not implemented");
}
}
}
答案 0 :(得分:2)
您正在将IQuery<TResult> query
对象传递给Validate(GetSite)
方法 - 该方法需要GetSite
类型。
即使GetSite
实现IQuery<TResult>
,编译器也不能保证IQuery<TResult> query
是GetSite
类型的对象 - 它也可能是其他类型的实现IQuery<TResult>
无法进行演员表。