简体   繁体   English

C#解析通用类型

[英]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> queryGetSite类型的对象-也可能是实现IQuery<TResult>其他类型,其中无法进行GetSite转换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM