I have an interface that takes 2 generic type parameters and an implementation that only takes one.
How does one setup the dependency mapping in the DI container?
Given the psuedo code:
interface IDataStore<TEntity, TQuery>
{
TEntity GetById(string id);
TEntity[] Query(TQuery query);
}
class MySqlQuery {}
class MySqlDataStore<TEntity> : IDataStore<TEntity, MySqlQuery>
{
TEntity GetById(string id);
TEntity[] Query(SqlQuery query);
}
class DynamoDBQuery {}
class DynamoDBDataStore<TEntity> : IDataStore<TEntity, DynamoDBQuery>
{
TEntity GetById(string id);
TEntity[] Query(DynamoDBQuery query);
}
The following compiles but failes to resolve at runtime because there are a differing amount of type arguments:
services.AddSingleton(typeof(IDataStore<,>), typeof(MySqlDataStore<>));
And given:
services.AddSingleton(typeof(TInterface), typeof(TImplementation));
there doesn't seem to be a factory method for TImplementation that gives access to TInterface, because if there was one could just construct the concrete type in the factory with (psuedo code):
services.AddSingleton(
typeof(IDataStore<,MySqlQuery>),
(interfaceType, serviceProvider) => typeof(MySqlDataStore<>).MakeGenericType(interfaceType.GenericArguments[0]));
I know one option is to just scan all assemblies for all TEntity and constuct the interface to concrete type mappings on application startup so will probably go with that but wondered if anyone has any ideas on how to do the mapping on service resolution instead.
For anyone interested, this is the code to do the registration on startup