HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpModerate

MVC 5 & EF 6 - Repository & Unit of Work Pattern

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
mvcworkrepositorypatternunit

Problem

I have been looking through Code Review on the subject of Unit of Work and Repository patterns and realised that my implementation appears to provide very similar functionality but in reverse class order/hierarchy. (Couldn't think of a better way to describe it sorry)

This is one of the questions I feel mine is similar to but in reverse.

I have added my code below. I would appreciate any feedback on my implementation you can offer regarding correctness, efficiency, and any suggestions.

UnitOfWork.cs - UnitOfWork + IUnitOfWork

```
public class UnitOfWork : IUnitOfWork
{
PropertyInfoEntities _context = null;

public IXXXXXRepository XXXXXRepository { get; set; }
public IPersonRepository PersonRepository { get; set; }
public IPersonLoginRepository PersonLoginRepository { get; set; }
public IPropertyApplicationRepository PropertyApplicationRepository { get; set; }
public ISaleTypeRepository SaleTypeRepository { get; set; }
public IStatusRepository StatusRepository { get; set; }
public ITownRepository TownRepository { get; set; }
public ITypeRepository TypeRepository { get; set; }

public UnitOfWork() : this(new PropertyInfoEntities()) { }

public UnitOfWork(PropertyInfoEntities context)
{
_context = context;
InitRepositories();
}

private void InitRepositories()
{
XXXXXRepository = new XXXXXRepository(_context);
PersonRepository = new PersonRepository(_context);
PersonLoginRepository = new PersonLoginRepository(_context);
PropertyApplicationRepository = new PropertyApplicationRepository(_context);
SaleTypeRepository = new SaleTypeRepository(_context);
StatusRepository = new StatusRepository(_context);
TownRepository = new TownRepository(_context);
TypeRepository = new TypeRepository(_context);
}

public void Save()
{
_context.SaveChanges();
}

#region IDisposable Members

public void Dispose()

Solution

I get what you mean by "reversed":

As opposed to:

Makes sense, at least to me - the way I see UoW/Repository pattern (everybody seems to have their own take at this one, eh?), Entity Framework's DbContext is a unit-of-work, and an IDbSet is a repository.

Hence, I tend to agree with having unit-of-work depend on repositories and not the opposite. When we inherit DbContext, we expose IDbSet properties, and this is exactly what you've got here.

Thing is, if DbContext is a unit-of-work, and IDbSet is a repository... then what need is there to wrap it with infrastructure code that
only buys additional complexity?

You're not showing how your UoW implementation is used in your controllers, but if you're using it directly, then you're playing with IQueryable and you're not really wrapping anything, EF and Linq-to-Entities is bleeding out of every usage you're making of every repository call, making the extra abstraction not-quite-an-abstraction.

I have yet to see a UoW+Repository implementation with EF that will show me real benefits over using the DbContext directly in the controllers (or, more appropriately, in a dedicated, testable service class).

Instead, I tend to just go like this:

public Interface IUnitOfWork
{
    IDbSet Set();
    void Save();
}

public class SomeContext : DbContext, IUnitOfWork
{
    public void Save() // base method returns an int that I don't want
    {
        base.SaveChanges(); // qualifier "base" is redundant, specified for readability
    }
}


Then, I can inject an IUnitOfWork and get an IDbSet for any entity type, and do everything EF has in store for me with that interface; the IUnitOfWork merely enables mocking, so I can set it up to return a mock IDbSet when Set() is called. Keep. It. Simple.

Code Snippets

public Interface IUnitOfWork
{
    IDbSet<TEntity> Set<TEntity>();
    void Save();
}

public class SomeContext : DbContext, IUnitOfWork
{
    public void Save() // base method returns an int that I don't want
    {
        base.SaveChanges(); // qualifier "base" is redundant, specified for readability
    }
}

Context

StackExchange Code Review Q#47144, answer score: 12

Revisions (0)

No revisions yet.