Mathias Hove Mathias Hove - 3 months ago 42
ASP.NET (C#) Question

Simple repository asp.net mvc with entity framework

I am about to start a small/medium sized project. I am by no means a software architect. But i tend to question every move i make at times. Since i want to do things correct.

I found a way to implement a simple repository, and i wanted to know if this is a "correct" way of doing it. I came to this solution, since i know what is going on, and not taking in something to complex before i have the knowledge :)

Here it goes.

Unit of work

Where i make sure i to keep all my repositories under the same dbcontext. In my uof i can access all repo's when calling it from the controller.


public class UnitOfWork : IDisposable
{
private ContactRepository _contactRepo;
private ApplicationDbContext _entities;

public UnitOfWork(ApplicationDbContext entities)
{
_entities = entities;
}

public ContactRepository ContactRepo
{
get
{
if (_contactRepo == null)
{
_contactRepo = new ContactRepository(_entities);
}
return _contactRepo;
}
}


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

private bool disposed = false;

protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
_entities.Dispose();
}
}
this.disposed = true;
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}


ContactRepository

This is a short example of a repository, where it recieves the dbcontext and uses it to grab whatever data i want


public class ContactRepository
{
private ApplicationDbContext _entities;

public ContactRepository(ApplicationDbContext entities)
{
_entities = entities;
}

public IEnumerable<Contact> GetAll()
{
return _entities.Contacts;
}
}


Controller

Short example of controller


public class ContactController : Controller
{

UnitOfWork uow = new UnitOfWork(new ApplicationDbContext());

public ActionResult Index()
{
var contacts = uow.ContactRepo.GetAll();
return View(contacts);
}



protected override void Dispose(bool disposing)
{
uow.Dispose();
base.Dispose(disposing);
}
}


In this way i will have access to all my repositories under the same dbcontext which i was aiming for.

I know things can be done smarter/different. With for example a extendable generic repo. But in this case i am aiming for something simple and understandable. But still dont want to make a huge mistake, if there is a major flaw.

Do you see any major flaws with this way of handling data trough entity framework?

Answer

If you're aiming for something simple then just use Entity Framework but if you're going to use the repository pattern I would encourage you to do it properly.

Two of the biggest motivators for using repository are:

  1. You want to simplify CRUD applications to your database.This is done through the use of interfaces and generics
  2. You want to the ability to test the business logic in isolation from external dependencies.Again, this is done through the use of interfaces

Below will take you two minutes to implement but then at least you know you're doing it right, because at the moment you're trying to implement a great pattern in an ineffective way.

Generic interface:

    public interface IRepository<T>
    {
        T GetById(int id);
        IEnumerable<T> List();
        IEnumerable<T> List(Expression<Func<T, bool>> predicate);
        void Add(T entity);
        void Delete(T entity);
        void Update(T entity);
    }

Generic repository:

    public abstract class EntityBase
    {
    }

    public class DBRepository<T> : IRepository<T> where T : EntityBase
    {
        private readonly DbContext _dbContext;

        public DBRepository(DbContext dbContext)
        {
            _dbContext = dbContext;
        }

        public virtual T GetById(int id)
        {
            return _dbContext.Set<T>().Find(id);
        }

        public virtual IEnumerable<T> List()
        {
            return _dbContext.Set<T>().AsEnumerable();
        }

        public virtual IEnumerable<T> List(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
        {
            return _dbContext.Set<T>()
                   .Where(predicate)
                   .AsEnumerable();
        }

        public void Add(T entity)
        {
            _dbContext.Set<T>().Add(entity);
        }

        public void Update(T entity)
        {
            _dbContext.Entry(entity).State = EntityState.Modified;
        }

        public void Delete(T entity)
        {
            _dbContext.Set<T>().Remove(entity);
        }

Unit of work:

public class UnitOfWork : IDisposable
{
    private bool disposed = false;
    private ApplicationDbContext  context = new ApplicationDbContext();

    private IRepository<Contact> _contactRepository;

    public IRepository<Contact> ContactRepository
    {
        get
        {
            if (this._contactRepository == null)
                this._contactRepository = new DBRepository<Contact>(context);
            return _contactRepository;
        }
    }

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

    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
                context.Dispose();
        }
        this.disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}
Comments