[英]C# resolving generic types
I am playing around with a test project. 我正在玩一个测试项目。 I am trying to implement a CQS pattern and I am getting close to wrapping up the initial tests. 我正在尝试实现CQS模式,并且接近完成初始测试。 I have run into an issue with trying to resolve my IQueryValidtor<>
and IQueryHandler<,>
classes. 我在尝试解析IQueryValidtor<>
和IQueryHandler<,>
类时IQueryHandler<,>
。 The method resolves them alright, but when i try to access the interface methods implemented in the concrete class, i get 该方法可以解决它们,但是当我尝试访问具体类中实现的接口方法时,我得到了
The best overloaded method match for 'MyProjectsNamespace.GetSiteValidator.Validate(MyProjectsNamespace.Queries.GetSite)' has some invalid arguments. 最佳重载方法匹配'MyProjectsNamespace.GetSiteValidator.Validate(MyProjectsNamespace.Queries.GetSite)'有一些无效的参数。
I am basing my code on this answer I found . 我将代码基于找到的答案 。 Everything appears to be lining up during design time, but run time is a different story. 在设计时一切似乎都在排队,但运行时则完全不同。
I am including all of the interfaces, implementations, and unit tests that I am working with on this issue. 我将包括与此问题有关的所有接口,实现和单元测试。 The first unit test is actually working. 第一个单元测试实际上正在工作。 It is the last two that are actually trying to use the resolved classes. 实际上,这是最后两个尝试使用已解析的类的方法。 I am using Autofac for my dependency injection. 我正在使用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();
}
}
The code above is all of the interfaces and concrete classes used in this problem. 上面的代码是此问题中使用的所有接口和具体类。 The code below is the dispatcher class where i am having the issue. 下面的代码是我遇到问题的调度程序类。
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");
}
}
}
You are passing an IQuery<TResult> query
object to the Validate(GetSite)
method - the method requires a GetSite
type. 您正在将IQuery<TResult> query
对象传递给Validate(GetSite)
方法-该方法需要GetSite
类型。
Even though GetSite
implements IQuery<TResult>
, The compiler can't guarantee that IQuery<TResult> query
is an object of type GetSite
- it could also be some other type implementing IQuery<TResult>
where a cast is not possible. 即使GetSite
实现了IQuery<TResult>
,编译器也不能保证IQuery<TResult> query
是GetSite
类型的对象-也可能是实现IQuery<TResult>
其他类型,其中无法进行GetSite
转换。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.