I am creating a new project using business objects (Employee, Product). Due to constraints, I am not using LINQ to SQL or any ORM Mapper.
I have to hand code the Data Access Layer(s). I am interested in using the 'Repository Pattern'.
According to what I understand, I have to create a generic repository IRepository
which is implemented by all repositories ProductRepository, EmployeeRepository
.
What confuses me is that different business objects have different requirements. For example:
ProductRepository
GetAllProducts ();
GetProductById (int id);
GetProductByMaxPrice (double price);
GetProductByNamePrice (string name, double Price);
Get... (...);
EmployeeRepository
GetEmployeeByAge ();
GetEmployeeByJob (string description);
GetEmployeeBySalary (double salary);
Get... (...); //and so on
How can I create a generic repository which meets different data access requirements of different objects?
I have read a lot of theory regarding Repository Pattern but would really appreciate a working example.
Additionally, if I can create all repositories using a generic repository, using the factory pattern becomes easy aswell. For example:
interface IRepository
{
....
}
ProductRepository : IRepository
{
....
}
EmployeeRepository : IRepository
{
....
}
Then we can use the factory pattern effectively as:
IRepository repository;
repository = new ProductRepository ();
repository.Call_Product_Methods ();
repository = new EmployeeRepository ();
repository.Call_Employee_Methods ();
Best Answer
The repository Pattern is a great pattern to use, but if it is not done correctly, instead of making your life easier, it will be a huge pain!
So, the best possible way to do this (since you dont want to use EF or other ORM) is by creating a generic interface, and then a base abstract implementation. This way you dont need to code each repository, you can just instantiate them by the type!
And after this, if you have any particular method specific to some of your entities, you can all inherit from the Repository and override or add methods and properties as nedded.
If you want to use the Repository Pattern, i also suggest that you use the IUnitOfWork pattern, and keep it separated from the repository.
Both interfaces should look something like this:
The very simple IUnitOfWork:
And them, the Repository interface, using generic:
The methods .Add(), .Delete() should not send anything to the database, but they should always send the changes to the IUnitOfWork (that you can implement in you DAL class), and only when you call the .Save() method of the IUnitOfWork you will save things to the Database.
I have implemented my Repository class using EntityFramework, and that makes things easier, but you can do it any way you want.
The code you will use will be somethin like this:
Like i said, with EF and the DbContext, this is a lot easier, to here are a small part of my Repository class:
This way you dont need to build a GetEmployeeByAge, you would simply write:
Or you could just call directly (no need to create the method)