1
\$\begingroup\$

I have some questions regarding a common implementation of the UoW, Repository Pattern and EF:

public interface IAppUow
{
    void Commit();
    IRepository<Customer> Customer{ get; } // IRepository<T>
    IOrderRepository Order{ get; }         // implements IRepository<T>
} 

My questions are:

  1. If I need to add a new repository of whatever type, I have to change the UoW. Is this a good practice? If not, is there a better way?

  2. If I run Commit() { context.SaveChanges(); }, it will save the state of all the context's repositories. Is this a good way?

\$\endgroup\$
5
\$\begingroup\$

This question is on the edge of being off-topic, there's really not much code to review here.

However your IAppUow interface has a number of flaws:

  • Naming: I don't see a need for the App part. I think a better name would be more like IUnitOfWork.
  • Inconsistency: You have IRepository<Customer>, and then IOrderRepository - why don't you have IRepository<Order> or IOrderRepository? When/if you do add repositories to your UoW interface, do you add a IRepository<Entity> or a IEntityRepository? This inconsistency makes it very hard to tell.

If I need to add a new repository of whatever type, I have to change the UoW. Is this a good practice? If not, is there a better way?

An interface shouldn't be designed to change, as every change to an interface is a breaking change. I think you're mixing up the abstraction with its implementation; UoW encapsulates a transaction - and these things can be committed or rolled back. Thus, if I were to wrap the EF UoW into another layer of abstraction (I'll get back to that), I'd have a void SaveChanges() and void DiscardChanges() methods on the UoW interface.

If I run Commit() { context.SaveChanges(); }, it will save the state of all the context's repositories. Is this a good way?

This is how Entity Framework works. DbContext is a unit of work; if you Dispose() the context before saving any changes, nothing gets to the database. If you SaveChanges(), the unit of work commits all changes made.

DbContext is an implementation of a unit of work - it exposes repositories (IDbSet<TEntity>) and a method to commit changes (and stuff about entity state management and model generation).

This might not be what you want to hear, but this answer sums up my thoughts pretty well: https://softwareengineering.stackexchange.com/a/214022/68834 - in short, you don't need the pattern if you're using an Object/Relational Mapper.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.