I understand the problem I am presenting here could be more like debate and there is no simple answer or simple solution :p. I am rather an inexperience programmer who passionate in writing applications. Hope some of you can give me some good starter points
:)
I have read a very good tutorial on the Repository Pattern using generic classes and Unity of Work. I would really like to apply this in my application. The one thing that made me decide on that was much to ability to implement tests--I think it is called
TDD. I feel l have a firm understanding of how it works. The tutorial is here on the ASP.Net Implementing
the Repository and Unit of Work Patterns in an ASP.NET MVC Application. The application I am working on is going to be written using MVC framework and C# with Razor in Visual Studio 2010 SP1. I also use Entity Framework 6 when I write this. Front-end
of that system is a collection of forms in order for data to gather, validate and save to database. The website is protected by login/password.
The problem is that I need my application to track who signs in, what has been done in terms of CRUD activity, what are the old and new values, which tables is affected and when activity was performed.
The repository pattern I've read cover only a simple CRUD methods with additional filtering / ordering data. I feel that a repository in my application would have to be more complex and do some extra work. Perhaps what I am talking about is not even one
repository. So I have a couple of questions:
Does it have to be one repository even if it's generic?
If not one repository, should I have a repository per table and its archive version, or should the business of all CRUD / archiving like updating / archiving, deleting /archiving old data be implemented in a repository per Creating, Updating, Deleting etc.
How can the Unity of Work be helpful here
I am guessing that to track user, I would need to send user information to repository or simply store it there like DbContext and use it every time it needed. As can be seen, I ask a lot of questions which may sound silly. I would simply like to have proper
approach before I get my hands into programming all this. I will be grateful for your comments, links, books etc. :)
Entity Framework already implements repository-per-table and unit of work patterns so there is no great need to implement your own on top of it. All you'll end up doing is having a repo with a bunch of single-line methods
public void AddPerson(Person p)
{
dbContext.Persons.Add(p);
}
all you're doing is slightly changing the syntax of adding things to your database. Doing your own repo becomes more valuable if you want to abstract how your data is stored, or you want a repo for entities that don't one-to-one match tables. For example
if you have an Order and OrderItem table then EF gives you an Order and OrderItem repo. You might want a repo that lets you manage things at the order level, and that repo understands how and when to get related data from OrderItems. So your order repo might
have a "GetTotalCostOfOrder" method.
RAZORmvcRepository
I'm afraid I no longer use this forum due to the new point allocation system.
I can only trust you on EF having already reposition. It's correct that we simply use dbContext.Table.function etc. Then, as far as I understand it, I agree EF has implemented this functionality but the main advantage of having own reposition is I think
decoupling from the database. I guess this is one of the reasons why you can implement testing, easily. It's really important to me. Do you have any suggestions how to do design tests without having reposition?
If you google "mocking entity framework dbcontext" you'll find some articles on how to do this. However using your own repo will indeed make testing, and TDD, easier.
RAZORmvcRepository
I'm afraid I no longer use this forum due to the new point allocation system.
Thanks. If I decided on my own Reposition, would you suggest anything on recording users' activities and saving / archiving records when CRUD operations are concerned? Is there any well-known pattern of doing this or am I just on my own here? I don't know
how exactly I should approach this problem in terms of my own repository.
What AidyF describes regarding DBContext is true. DbContext itself is already a UOW pattern so you don't have to duplicate. My advice is to create your own Generic IRepository and abstract generic BaseRepository and your implementation of Repository per
domain. For example, I do have an Employee, Address, Benefits Model. Here's a simple code snippets. You attack repository pattern on domain basis. Example, Customer Domain(may consist of few models), Order Domain(may consists of few models).
So for each domain, you could have CustomerRepository,OrderRepository, etc. These are testable in repository level. Hope this helps.
It may not be complete since I have to hide some of my complex implementations.
public interface IRepository<T>
{
IQueryable<T> GetAll();
T Get(int id);
int Insert(T entity);
int Update(T entity);
int Update(T entity, Expression<Func<T, object>>[] properties);
int Delete(T entity);
IQueryable<T> GetAllFromDatabase();
}
public abstract class BaseRepository<T> : IRepository<T> where T : class
{
protected IDatabaseContext DatabaseContext { get; private set; }
public abstract IQueryable<T> GetAll();
public abstract T Get(int id);
public abstract int Insert(T entity);
public abstract int Update(T entity);
public abstract int Delete(T entity);
public int Update(T entity, Expression<Func<T, object>>[] properties)
{
}
}
public interface IEmployeeRepository : IRepository<Employee>
{
}
public class EmployeeRepository: BaseRepository<Employee>, IEmployeeRepository
{
public EmployeeRepository(IDatabaseContext databaseContext): base(databaseContext)
{
}
public override IQueryable<Employee> GetAll()
{
var allEmployee = DatabaseContext.Set<Employee>();
return allEmployee;
}
Member
1 Points
14 Posts
Generic repository data patter in relatively more complex application. Need some advices on the d...
Feb 26, 2015 04:25 AM|Zbigman|LINK
Hi
I understand the problem I am presenting here could be more like debate and there is no simple answer or simple solution :p. I am rather an inexperience programmer who passionate in writing applications. Hope some of you can give me some good starter points :)
I have read a very good tutorial on the Repository Pattern using generic classes and Unity of Work. I would really like to apply this in my application. The one thing that made me decide on that was much to ability to implement tests--I think it is called TDD. I feel l have a firm understanding of how it works. The tutorial is here on the ASP.Net Implementing the Repository and Unit of Work Patterns in an ASP.NET MVC Application. The application I am working on is going to be written using MVC framework and C# with Razor in Visual Studio 2010 SP1. I also use Entity Framework 6 when I write this. Front-end of that system is a collection of forms in order for data to gather, validate and save to database. The website is protected by login/password.
The problem is that I need my application to track who signs in, what has been done in terms of CRUD activity, what are the old and new values, which tables is affected and when activity was performed.
The repository pattern I've read cover only a simple CRUD methods with additional filtering / ordering data. I feel that a repository in my application would have to be more complex and do some extra work. Perhaps what I am talking about is not even one repository. So I have a couple of questions:
I am guessing that to track user, I would need to send user information to repository or simply store it there like DbContext and use it every time it needed. As can be seen, I ask a lot of questions which may sound silly. I would simply like to have proper approach before I get my hands into programming all this. I will be grateful for your comments, links, books etc. :)
RAZOR mvc Repository
All-Star
37441 Points
9076 Posts
Re: Generic repository data patter in relatively more complex application. Need some advices on t...
Feb 26, 2015 05:17 AM|AidyF|LINK
Entity Framework already implements repository-per-table and unit of work patterns so there is no great need to implement your own on top of it. All you'll end up doing is having a repo with a bunch of single-line methods
all you're doing is slightly changing the syntax of adding things to your database. Doing your own repo becomes more valuable if you want to abstract how your data is stored, or you want a repo for entities that don't one-to-one match tables. For example if you have an Order and OrderItem table then EF gives you an Order and OrderItem repo. You might want a repo that lets you manage things at the order level, and that repo understands how and when to get related data from OrderItems. So your order repo might have a "GetTotalCostOfOrder" method.
RAZOR mvc Repository
Member
1 Points
14 Posts
Re: Generic repository data patter in relatively more complex application. Need some advices on t...
Feb 26, 2015 05:55 AM|Zbigman|LINK
Hi AidyF.
I can only trust you on EF having already reposition. It's correct that we simply use dbContext.Table.function etc. Then, as far as I understand it, I agree EF has implemented this functionality but the main advantage of having own reposition is I think decoupling from the database. I guess this is one of the reasons why you can implement testing, easily. It's really important to me. Do you have any suggestions how to do design tests without having reposition?
RAZOR mvc Repository
All-Star
37441 Points
9076 Posts
Re: Generic repository data patter in relatively more complex application. Need some advices on t...
Feb 26, 2015 05:57 AM|AidyF|LINK
If you google "mocking entity framework dbcontext" you'll find some articles on how to do this. However using your own repo will indeed make testing, and TDD, easier.
RAZOR mvc Repository
Member
1 Points
14 Posts
Re: Generic repository data patter in relatively more complex application. Need some advices on t...
Feb 26, 2015 06:16 AM|Zbigman|LINK
Thanks. If I decided on my own Reposition, would you suggest anything on recording users' activities and saving / archiving records when CRUD operations are concerned? Is there any well-known pattern of doing this or am I just on my own here? I don't know how exactly I should approach this problem in terms of my own repository.
RAZOR mvc Repository
All-Star
37441 Points
9076 Posts
Re: Generic repository data patter in relatively more complex application. Need some advices on t...
Feb 26, 2015 06:22 AM|AidyF|LINK
Look into "Unit of work" implementations.
RAZOR mvc Repository
Member
710 Points
225 Posts
Re: Generic repository data patter in relatively more complex application. Need some advices on t...
Feb 28, 2015 10:51 PM|itpreneur|LINK
Hi Zbigman,
What AidyF describes regarding DBContext is true. DbContext itself is already a UOW pattern so you don't have to duplicate. My advice is to create your own Generic IRepository and abstract generic BaseRepository and your implementation of Repository per domain. For example, I do have an Employee, Address, Benefits Model. Here's a simple code snippets. You attack repository pattern on domain basis. Example, Customer Domain(may consist of few models), Order Domain(may consists of few models).
So for each domain, you could have CustomerRepository,OrderRepository, etc. These are testable in repository level. Hope this helps.
It may not be complete since I have to hide some of my complex implementations.
public interface IRepository<T>
{
IQueryable<T> GetAll();
T Get(int id);
int Insert(T entity);
int Update(T entity);
int Update(T entity, Expression<Func<T, object>>[] properties);
int Delete(T entity);
IQueryable<T> GetAllFromDatabase();
}
public abstract class BaseRepository<T> : IRepository<T> where T : class
{
protected IDatabaseContext DatabaseContext { get; private set; }
protected BaseRepository(IDatabaseContext databaseContext)
{
DatabaseContext = databaseContext;
}
public abstract IQueryable<T> GetAll();
public abstract T Get(int id);
public abstract int Insert(T entity);
public abstract int Update(T entity);
public abstract int Delete(T entity);
public int Update(T entity, Expression<Func<T, object>>[] properties)
{
}
}
public interface IEmployeeRepository : IRepository<Employee>
{
}
public class EmployeeRepository: BaseRepository<Employee>, IEmployeeRepository
{
public EmployeeRepository(IDatabaseContext databaseContext): base(databaseContext)
{
}
public override IQueryable<Employee> GetAll()
{
var allEmployee = DatabaseContext.Set<Employee>();
return allEmployee;
}
public override Employee Get(int id)
{
return DatabaseContext.Set<Employee>().Include("Address").Include(d => d.Benefits).Single(x => x.Id == id);
}
public override int Insert(Employee entity)
{
DatabaseContext.Entry(entity).State = EntityState.Added;
DatabaseContext.Insert(entity);
return DatabaseContext.SaveChanges();
}
public override int Update(Employee entity)
{
DatabaseContext.Entry(entity).State = EntityState.Modified;
DatabaseContext.Update(entity);
return DatabaseContext.SaveChanges();
}
public override int Delete(Employee entity)
{
DatabaseContext.Delete(entity);
return DatabaseContext.SaveChanges();
}
}
RAZOR mvc Repository
Member
1 Points
14 Posts
Re: Generic repository data patter in relatively more complex application. Need some advices on t...
Aug 03, 2015 06:31 AM|Zbigman|LINK
Thanks for your answer itpreneur. It's really helpful. I hope it's still np as I came back so late :)
RAZOR mvc Repository
Participant
1906 Points
1166 Posts
Re: Generic repository data patter in relatively more complex application. Need some advices on t...
Sep 04, 2015 02:32 PM|madan535|LINK
Implementing the Repository and Unit of Work Patterns in an ASP.NET MVC Application (9 of 10)
http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
RAZOR mvc Repository