I'm feeling pretty dumb right now. Not sure why I can't solve this. I have a repository interface:
public interface ICollateralItemBaseImplementation<T> where T : CollateralItemBase
{
int Add(T collateralItem);
T Get(int collateralID);
}
and many implementations, each implementing one of the 10 models that inherit from CollateralItemBase
. For example:
internal sealed class CollateralItemCertifiedDepositRepository : ServiceBaseRepository, ICollateralItemBaseImplementation<CollateralItemCertifiedDeposit>
{
int Add(CollateralItemCertifiedDeposit collateralItem) { /*...*/ }
CollateralItemCertifiedDeposit Get(int collateralID) { /*...*/ }
}
Now i just need to switch on the incoming CollateralItemBase
type to get the repository I need:
private ICollateralItemBaseImplementation<???> GetRepository(CollateralItemBase item)
{
switch (item.GetType().Name)
{
case "CollateralItemCertifiedDeposit": return new CollateralItemCertifiedDepositRepository();
//...
}
I just need to figure out what to return from this method, for other methods to act on whichever repository I return. How do I refactor this to get it working? I'm pretty sure I have a covariance/contravariance problem. Again, I'm feeling pretty dumb, just drawing a blank.
Thanks.
You could do it in two stages. Add a non-generic base interface to ICollateralItemBaseImplementation
then cast to the generic version.
public interface ICollateralItemBaseImplementation
{
}
public interface ICollateralItemBaseImplementation<T> : ICollateralItemBaseImplementation
where T : CollateralItemBase
{
int Add(T collateralItem);
T Get(int collateralID);
}
public static class RepositoryFactory
{
public static ICollateralItemBaseImplementation<T> GetRepository<T>(T item)
where T : CollateralItemBase
{
return (ICollateralItemBaseImplementation<T>)GetRepositoryImpl(item);
}
private static ICollateralItemBaseImplementation GetRepositoryImpl<T>(T item)
where T : CollateralItemBase
{
switch (item.GetType().Name)
{
case "CollateralItemCertifiedDeposit":
return new CollateralItemCertifiedDepositRepository();
}
return null;
}
}
internal static class Program
{
static void Main()
{
var repo = RepositoryFactory.GetRepository(new CollateralItemCertifiedDeposit());
Debug.Assert(repo is CollateralItemCertifiedDepositRepository);
}
}