I have two complex class:
public class BaseRepository<EntityType> where EntityType : class
{
protected northwindDataContext context = new northwindDataContext();
public EntityType Get(object id)
{
return context.Set<EntityType>().Find(id);
}
public EntityType Save(EntityType entity)
{
// Do generic save things
}
}
public class BaseService<EntityType> where EntityType : class
{
public BaseRepository<EntityType> repo = new BaseRepository<EntityType>();
public EntityType Get(object id)
{
// Do generic get entities
return repo.Get(id);
}
}
Then i have multiple "services" class where sometimes (Not always) i need to "replace" the repository to add some "extra" funcionality.
public class UserRepository : BaseRepository<User>
{
public User Get(object id)
{
// Do specific user get including Role DP
return context.Users.Include("Role").Find(id);
}
}
public class UserService : BaseService<User>
{
public UserRepository repo = new UserRepository();
}
Using this format the instance of UserService call to BaseRepository.Get() instead of UserRepository.Get().
The only way to do what i want is replicate code like this:
public class UserService : BaseService<User>
{
public UserRepository repo = new UserRepository();
public User Get(object id)
{
// This call to UserRepository.Get()
return repo.Get(id);
}
}
The real problem is that i have 29 "Repositories", so i need add "Get(int)", "Get(predicate)", "Save(entity)", "Save(IEnumerable)", "Delete(entity)" and "Delete(IEnumerable)", and that makes a kind of awkward code.
Is there any way to replace the property "repo" in BaseService so that BaseService methods call the repo subclass?
It sounds like what you really want is for the BaseService<T>.repo
field (it's a field, not a property - and I'd discourage you from using public fields, but that's a different matter) to be the appropriate kind of repository for the type. That's easy enough to do - just don't create it in BaseService<T>
. Instead, pass it up the constructor chain:
// Type parameter renamed to follow normal .NET naming conventions
public abstract class BaseService<T> where T : class
{
private readonly BaseRepository<T> repo;
protected BaseService(BaseRepository<T> repo)
{
this.repo = repo;
}
public T Get(object id)
{
// Do generic get entities
return repo.Get(id);
}
}
public class UserService : BaseService<User>
{
public UserService() : base(new UserRepository())
{
}
}
In fact, if UserService
isn't providing any other value, you may only need a Service<T>
, non-abstract and with a public constructor to take the repo. Then you'd just use:
var userService = new Service<User>(new UserRepository());
for example.
See more on this question at Stackoverflow