Reputation: 5146
I'm using a unit of work / generic repository pattern almost identical to the example Microsoft provides, and it works great. However, the need has recently arisen for some methods that are only applicable to a particular type of repository.
For example, say I have two classes corresponding to database tables: People
and Spaceships
.
unitofwork.People
is a Repository<Person>
and unitofwork.Spaceships
is a Repository<Spaceship>
. While both repositories have the methods I defined in
public class Repository<TEntity> where TEntity : class, IEntity
what if I want some Person
-specific methods to be available on unitofwork.People
? Is this possible?
Upvotes: 0
Views: 237
Reputation: 78545
You could make Repository<T>
an abstract class. Then each entity must have their own implementations:
abstract class RepositoryBase<TEntity> where TEntity : class, IEntity {
void Add(TEntity entity);
...
}
class PeopleRepository : RepositoryBase<Person> {
string GetPersonName();
}
class SpaceshipRepository : RepositoryBase<Spaceship> {
void Fly();
}
You'd then implement the classes as:
unitofwork.People = new PeopleRepository();
unitofwork.People.Add(new Person()); // Can access the base class
Console.WriteLine(unitofwork.People.GetPersonName()); // People-specific methods
unitofwork.Spaceships = new SpaceshipRepository();
If you want to be able to initialise an instance of the base repository, there is no need to mark it as abstract
:
class Repository<TEntity> where TEntity : class, IEntity {
void Add(TEntity entity);
}
class PeopleRepository : Repository<Person> {
string GetPersonName();
}
If you want to stop the PeopleRepository
from providing its own methods, then you can use the sealed
modifier:
class Repository<TEntity> where TEntity : class, IEntity {
sealed protected void Add(TEntity entity);
}
Upvotes: 2