The app I’m developing needs to be able to pull from several different data sources, including a couple SQL databases. Not ideal, but it’s an app designed to integrate several existing applications under one roof so I have to work with the schema I have.
Anyway, I’m using the Repository model, and setting up a repository per data source so I only have to make and keep the connections I need at any given point. So, I have to split up my domain model according to the repository that saves a particular domain object, and I have to enforce that objects passed to a generic Save<T> and Query<T> method are of a type it can actually work with. I tried this, and lo and behold, it compiles:
public interface IDomainObject{...}
public interface IOneDomainObject:IDomainObject{...}
public interface IAnotherDomainObject:IDomainObject{...}
public interface IRepository<TRest> where TRest:IDomainObject
{
...
public void Save<T>(T objectToSave) where T:class,TRest //<-- sweet! Didn't think that would work!
public IQueryable<T> Query<T>() where T:class,TRest
...
}
public interface ISecurityRepository:IRepository<IOneDomainObject>{}
public interface IOtherRepository:IRepository<IAnotherDomainObject>{}
So I’m feeling clever, however I’m sure Occam’s Razor applies here somewhere. Does this smell, or is it a valid way to define common functionality across classes that act on diverging object hierarchies?
Code like this is the very reason that generics were added to C# in the first place. Common algorithms applied to different types.