I am struggling with what I believe is a covariance/contravariance problem with my design. I want return a generic object which is only known at run time.
I have the following classes/interfaces
public interface IBaseRepository
{
int UserId { get; set; }
// Retrieve
SyncData GetRetrieveData();
// Update
SyncData GetUpdateData();
}
public interface IDomainRepository<T> : IBaseRepository where T : IDomainObject
{
object GetValue(T domainObject, string id);
void SetValue(T domainObject, string id, object value);
// retrieve data
BatchResults<T> Retrieve();
// update data
BatchResults<T> Update(SynchroniseList synchroniseList);
}
I have some implementations of these:
public abstract class BaseRepository : IBaseRepository
{
public int UserId { get; set; }
public virtual SyncData GetRetrieveData()
{
return new SyncData();
}
public virtual SyncData GetUpdateData()
{
return new SyncData();
}
}
public MyTaskRepository : BaseRepository, IDomainRepository<MyTask>
{
public object GetValue(MyTask domainObject, string id)
{
return domainObject.GetValue();
}
void SetValue(MyTask domainObject, string id, object value)
{
domainObject.SetValue();
}
// retrieve data
public BatchResults<MyTask> Retrieve()
{
// do stuff specific to MyTask
return new BatchResults<MyTask>();
}
// update data
BatchResults<T> Update(SynchroniseList synchroniseList)
{
// do stuff specific to MyTask
return new BatchResults<MyTask>();
}
}
public MyOtherTaskRepository : BaseRepository, IDomainRepository<MyOtherTask>
{
...
}
The problem I am having is when using this repository. In a form I have
IBaseRepository repo = RepositoryFactory.Create(some parameters);
This returns a IDomainRepository which allows my to get/set retrieve/update data.
However, I dont know how to call Retrieve/Update as I cant cast to IDomainRepository because I dont know what domain object I will be working with.
I have been reading up on covariance/contravariance as I am thinking it has something to do with that However, I also have the feeling that my design is wrong in the sense I have made this overly complicated. I believe I could implement this in say c# 2.0 so I think I shouldnt event be concerned about covariance/contravariance.
Is it my design or do I need to sort out my in/out interfaces?