patterncsharpMinor
Generic repository pattern
Viewed 0 times
patterngenericrepository
Problem
Please have a through look my custom implementation of generic repository pattern and suggest anything I may be lacking.
Generic Repository Interface
Implementation of Generic Repository Interface
```
public class UserRepository : IGenericRepository
{
private ModelDBEntities dataContext = null;
public UserRepository()
{
this.dataContext = new ModelDBEntities();
}
public UserRepository(ModelDBEntities dataContext)
{
this.dataContext = dataContext;
}
public IEnumerable SelectAll()
{
return dataContext.Users;
}
public User SelectByID(object argId)
{
long userId = long.Parse(argId.ToString());
return dataContext.Users.Single(u => u.UserId == userId);
}
public void Insert(User obj)
{
dataContext.Users.AddObject(obj);
}
public void Update(User obj)
{
if (obj.EntityState == EntityState.Detached)
dataContext.Users.Attach(obj);
dataContext.ObjectStateManager.ChangeObjectState(obj, System.Data.EntityState.Modified);
}
public void
- I am using a generic interface with 6 methods
- I'll be using a repository class for each entity type (e.g
UserRepository,ProductRepository,StoreRepository) which are not only going to implement the generic interface but also can add additional methods as per the need with respect to each repository class. for example:
UserRepositorycan add a new method named asCountUsers()which gets called from controller.
ProductRepositorycan add a new method named asGetExpiredProducts()which gets called from controller.
- I am declaring
IGenericRepositoryinUserController, similarly in other controllers and usingrepositoryPattern.
Generic Repository Interface
public interface IGenericRepository : IDisposable where T : class
{
IEnumerable SelectAll();
T SelectByID(object id);
void Insert(T obj);
void Update(T obj);
void Delete(object id);
void Save();
}Implementation of Generic Repository Interface
```
public class UserRepository : IGenericRepository
{
private ModelDBEntities dataContext = null;
public UserRepository()
{
this.dataContext = new ModelDBEntities();
}
public UserRepository(ModelDBEntities dataContext)
{
this.dataContext = dataContext;
}
public IEnumerable SelectAll()
{
return dataContext.Users;
}
public User SelectByID(object argId)
{
long userId = long.Parse(argId.ToString());
return dataContext.Users.Single(u => u.UserId == userId);
}
public void Insert(User obj)
{
dataContext.Users.AddObject(obj);
}
public void Update(User obj)
{
if (obj.EntityState == EntityState.Detached)
dataContext.Users.Attach(obj);
dataContext.ObjectStateManager.ChangeObjectState(obj, System.Data.EntityState.Modified);
}
public void
Solution
I have created generic repositories many times and what I found was that you're going to need to create interfaces for each entity typed repository.
So
Update
I realise this update comes a long time after the question, but time has past and experience has been gained.
You don't necessarily need a new interface for entity type. IoC containers can inject a specific implementation based on the generic parameter of the IGenericRepositoy interface. You will need an interface however for each implementation that has specific methods for that type, such as
You could also remove the generic parameter from the interface and move the where clause to each method:
then implement a
this would mean that any implementation of a type specific repository could just inherit this saving you some work
You can then decide on what you want to inject into your controller, if you just want the base CRUD methods then you will only need to pass in the implementation of IGenericRepository and use for several types.
So
IUserRepository that implements IGenericRepository, this way you'll be able to- Inject the repository easier with Inversion Of Control
- Create extra methods for each entity type as and when
- Test your controller easier
Update
I realise this update comes a long time after the question, but time has past and experience has been gained.
You don't necessarily need a new interface for entity type. IoC containers can inject a specific implementation based on the generic parameter of the IGenericRepositoy interface. You will need an interface however for each implementation that has specific methods for that type, such as
GetExpiredProducts() as mentioned in the initial question.You could also remove the generic parameter from the interface and move the where clause to each method:
public interface IGenericRepository : IDisposable
{
IEnumerable SelectAll() where T : class;
T SelectByID(object id) where T : class;
void Insert(T obj) where T : class;
void Update(T obj) where T : class;
void Delete(object id);
void Save();
}then implement a
GenericRepository class:public class GenericRepository : IGenericRepository
{
public GenericRepository()
{
blah...
}
public GenericRepository(ModelDBEntities dataContext)
{
blah...
}
public IEnumerable SelectAll() where T : class
{
blah...
}
public T SelectByID(object argId) where T : class
{
blah...
}
public void Insert(T obj) where T : class
{
blah...
}
public void Update(T obj) where T : class
{
blah...
}
public void Delete(object argId)
{
blah...
}
public void Save()
{
blah...
}
}this would mean that any implementation of a type specific repository could just inherit this saving you some work
public interface IUserRepository : IGenericRepository
{
int CountUsers();
}
public class UserRepository : GenericRepository, IUserRepository
{
public UserRepository()
{
blah...
}
public UserRepository(ModelDBEntities dataContext)
: base(dataContext)
{
blah...
}
public int CountUsers()
{
blah...
}
}You can then decide on what you want to inject into your controller, if you just want the base CRUD methods then you will only need to pass in the implementation of IGenericRepository and use for several types.
Code Snippets
public interface IGenericRepository : IDisposable
{
IEnumerable<T> SelectAll() where T : class;
T SelectByID(object id) where T : class;
void Insert(T obj) where T : class;
void Update(T obj) where T : class;
void Delete(object id);
void Save();
}public class GenericRepository : IGenericRepository
{
public GenericRepository()
{
blah...
}
public GenericRepository(ModelDBEntities dataContext)
{
blah...
}
public IEnumerable<T> SelectAll() where T : class
{
blah...
}
public T SelectByID(object argId) where T : class
{
blah...
}
public void Insert(T obj) where T : class
{
blah...
}
public void Update(T obj) where T : class
{
blah...
}
public void Delete(object argId)
{
blah...
}
public void Save()
{
blah...
}
}public interface IUserRepository : IGenericRepository
{
int CountUsers();
}
public class UserRepository : GenericRepository, IUserRepository
{
public UserRepository()
{
blah...
}
public UserRepository(ModelDBEntities dataContext)
: base(dataContext)
{
blah...
}
public int CountUsers()
{
blah...
}
}Context
StackExchange Code Review Q#69956, answer score: 3
Revisions (0)
No revisions yet.