I have the following interfaces:
public interface IQueryHandler<in TQuery, out TResult> where TResult : class
where TQuery : IQuery<TResult>
{
TResult Handle(TQuery query);
}
public interface IQuery<TResult> // Doesn't require anything special, just used to guarantee that IQueryHandlers get the right parameters.
{
}
It's intended to be used by IQueryHandlers
which will take in an IQuery<TResult>
which defines a query that returns an object of type TResult
. The IQueryHandler
's Handle
method then returns a TResult
.
I have the interface implemented on a DataQueryHandlers
class:
public class DataQueryHandlers : IQueryHandler<GetDataById, SomeData>
{
private IDataSource source;
public DataQueryHandlers(IDataSource source)
{
this.source = source
}
public SomeData Handle(GetDataById query)
{
// Get the data here and return SomeData object
}
}
where SomeData
is a data entity, and GetDataById
is an IQuery<SomeData>
However, when I try to instantiate a specific instance:
private IQueryHandler<IQuery<SomeData>, SomeData> dataQueryHandlers;
private IDataSource source;
source = new DataSource(); // some data provider
dataQueryHandlers = new DataQueryHandlers(datasource); // This line won't compile
I get a compiler error:
Cannot implicitly convert type
DataQueryHandlers
toIQueryHandler<IQuery<SomeData>, SomeData>
. An explicit conversion exists (are you missing a cast?)
I'm sure this is a covariant/contravariant related problem, but I fail to see where the mismatch is. Is there a problem with my in/out generic modifiers? Is what I'm trying to do fundamentally incorrect in some way? Am I missing some obvious "hair on a fish" scenario here?
You should change your derived class to generic one to be able to do it. Change it to this:
More about Generic Classes you can find MSDN