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

Entity Framework using Repository Pattern, Unit of Work and Unity - viable approach?

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

Problem

Using a combination provided from this example and this implementation, I'm creating a solution that decouples the UnitOfWork class from the individual repositories, as they violate the Open-Closed Principle: every time you added a new repository you would have to modify the UnitOfWork class. I am using Unity 3.0 as the IoC container to wire up dependencies, together with Unity Bootstrapper for ASP.NET MVC and its PerRequestLifetimeManager to handle automatically disposing the UnitOfWork and DbContextFactory classes.

Here's my proposed demo solution:

Repositories

public interface IRepository where TEntity : class
{
    TEntity Create();
    // omitted for brevity
}

public class Repository : IRepository
    where TEntity : class
{       
    private readonly DbContext _context;

    public Repository(IUnitOfWork uow)
    {
        _context = uow.Context;
    }

    public virtual TEntity Create(TEntity entity)
    {
        return _context.Set().Add(entity);         
    }   

    // omitted for brevity      
}

public interface IEmployeeRepository : IRepository
{
}

public interface ICustomerRepository : IRepository
{
}

public class EmployeeRepository : Repository
{
    public EmployeeRepository(IUnitOfWork uow)
        : base(uow)
    {
    }
}

public class CustomerRepository : Repository
{
    public CustomerRepository(IUnitOfWork uow)
        : base(uow)
    {
    }
}


DbContext Factory

public interface IDbContextFactory
{
    DbContext GetContext();
}

public class DbContextFactory : IDbContextFactory
{
    private readonly DbContext _context;

    public DbContextFactory()
    {
        _context = new MyDbContext("ConnectionStringName");
    }

    public DbContext GetContext()
    {
        return _context;
    }
}


Unit Of Work

```
public interface IUnitOfWork
{
void SaveChanges();
DbContext Context { get; }
}

public class UnitOfWork : IUnitOfWork, IDisposable
{
private readonly DbContext _context;
private boo

Solution

While I'm not sure of the safety of PerRequestLifetimeManager, one thing I'd recommend changing in your repository is to avoid inheritance from Repository.

Instead of

public class EmployeeRepository : Repository
{
    ...
}


do

public class EmployeeRepository : IEmployeeRepository
{
    private Repository _genericRepo;
    ...
}


When you don't want to implement all methods of Repository in your EmployeeRepository (like say, you don't want to delete Employees), it leads to cleaner code. You avoid exposing the unwanted interface, you avoid throwing exceptions if the Delete method is called. And instead of calling base.SomeMethod(), you call _genericRepo.SomeMethod(), thus getting the same advantage of code re-use.

Code Snippets

public class EmployeeRepository : Repository<Employee>
{
    ...
}
public class EmployeeRepository : IEmployeeRepository
{
    private Repository<Employee> _genericRepo;
    ...
}

Context

StackExchange Code Review Q#32071, answer score: 3

Revisions (0)

No revisions yet.