ASP.NET MVC, EntityFramework, DBContext, Repository in a different Project

asp.net asp.net-mvc c# data-access-layer entity-framework

Question

I'm now working on a MVC 5 for ASP.NET project, and I'm attempting to tidy up the architecture to make future contributors' jobs as simple and straightforward as feasible.

My EntityFramework models, such as IdentityUser and AccountViewModel, have been transferred to a Class library project within the same solution as a start. The current primary MVC project makes reference to this.

However, I'm now thinking about making a separate Data Access Layer project that will house both the data access layer and the DbContext (or DbContexts, if I decide to use more than one DbContext). What is the most effective way to go with this?

The Model project will be referenced by this DAL project, while only the DAL project is referenced by the main MVC project.

Upon finishing this piece! I was wondering if utilizing EntityFramework made the repository pattern outdated.

Thus, I have two main inquiries:

1) How should DAL be separated into a separate project?

2) How can I use EF to retrieve database content the best way?

1
11
1/2/2014 4:48:55 PM

Accepted Answer

Your inquiry is somewhat general. What do you mean, for instance, by "the best method to retrieve the database content using EF"? The method that performs the best?

I'll try to respond by outlining a solution that employs the repository pattern and that I personally prefer (and typically use some variation of). You could argue that you wouldn't need the repository design if you used your EF sets as a repository directly, but I prefer to wrap those in one of my own.

I'll provide my personal preference, which would work well for a regular online project, since I have no idea what you mean by the "best approach"

Although I won't be releasing all the code necessary to make it fully functioning, you should still understand what is happening.

(4 projects) Setup

UI ---> Domain.Logic (w. Domain.Models) ————————-> Data (Holding the EF Context).

Data:

public partial class EFContextContainer : DbContext 
enter code here
public EFContextContainer ()
        : base("name=EFContextContainer")
    {
    }

public DbSet<IdentityUser> IdentityUsers { get;set; } 

a wrapper that returns the context:

public static class Database
{
    public static EFContextContainerGetContext()
    {
        return new EFContextContainer();
    }

}

You might set up a repository in the following manner:

Interface:

public interface IRepository<T> where T : class
{
    IQueryable<T> GetAll();
    T GetById(Guid id);
    void Add(T entity);
    void Update(T entity);
    void Delete(T entity);
    void Delete(Guid id);
}

For the purpose of brevity, implementation (which only implemented the Add(T entity)):

public class EFRepository<T> : IRepository<T>, IDisposable where T : class
{
    public EFRepository(DbContext dbContext)
    {
        if (dbContext == null)
            throw new ArgumentNullException("dbContext");
        DbContext = dbContext;
        DbSet = DbContext.Set<T>();

    }

    protected DbContext DbContext { get; set; }

    protected DbSet<T> DbSet { get; set; }

    public virtual void Add(T entity)
    {
        DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
        if (dbEntityEntry.State != EntityState.Detached)
        {
            dbEntityEntry.State = EntityState.Added;
        }
        else
        {
            DbSet.Add(entity);
        }
    }

public void Dispose()
    {
        DbContext.Dispose();
    }

}

Domain:

IdentityUserManager would be a class in Domain.Models under Domain.Logic.

public class IdentityUserManager
{
    public void Add(IdentityUser idUser)
    {
        using(var idUserRepository = new EFRepository<IdentityUser>(Database.GetContext())
        {
            idUserRepository.Add(idUser);
        }
    }
}

UI:

[HttpPost]
public ActionResult Post(UserViewModel model)
{
    UserIdentity user = MapUser(model);
    var userManager = new IdentityUserManager();
    userManager.Add(user);

    return View(new UserViewModel());
}

Please excuse any spelling mistakes as this wasn't all written in Visual Studio.

Even though this code has the potential for much more abstraction, it would be absurd to present a complete solution here. For instance, you could combine the repository pattern with the excellent Work Unit pattern. So, use this as an illustration rather than a comprehensive manual for how to put this up. The setup might be much more organized than in this example.

I One-Page Apps you to look at the course by John Papa on Plural Sight for an in-depth look at the implementation of several of these patterns. He does a fantastic job of outlining the advantages of these patterns and how to use them.

7
10/29/2013 10:10:16 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow