C# resolving generic types -


i playing around test project. trying implement cqs pattern , getting close wrapping initial tests. have run issue trying resolve iqueryvalidtor<> , iqueryhandler<,> classes. method resolves them alright, when try access interface methods implemented in concrete class,

the best overloaded method match 'myprojectsnamespace.getsitevalidator.validate(myprojectsnamespace.queries.getsite)' has invalid arguments.

i basing code on this answer found. appears lining during design time, run time different story.

i including of interfaces, implementations, , unit tests working on issue. first unit test working. last 2 trying use resolved classes. using autofac dependency injection.

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> 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 of interfaces , concrete classes used in problem. code below dispatcher class having 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 null");         }          // use dynamic datatype because tresult not known @ 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 passing iquery<tresult> query object validate(getsite) method - method requires getsite type.

even though getsite implements iquery<tresult>, compiler can't guarantee iquery<tresult> query object of type getsite - other type implementing iquery<tresult> cast not possible.


Comments