Michiel Wouters
Michiel Wouters

Reputation: 99

Using ApplicationDbContext with Dependency Injection in an n-layered architecture

I have an application with 3 layers (Presentation - Business - Data) built with Asp.Net MVC Core 2.1

In my Presentation layer I have an ApplicationDbContext class which instantiates and fills a test database:

public class ApplicationDbContext : IdentityDbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        SeedData(builder);
    }

    // Database Tables
    public DbSet<Customer> Customers { get; set; }
    public DbSet<Ingredient> Ingredients { get; set; }
    public DbSet<Order> Orders { get; set; }
    public DbSet<OrderDetail> OrderDetails { get; set; }
    public DbSet<Pizza> Pizzas { get; set; }
    public DbSet<PizzaIngredient> PizzaIngredients { get; set; }

    // Fill Database with sample data
    private void SeedData(ModelBuilder builder)
    {
         // Seed data
    }

Said class is injected within the Startup.cs class (also in presentation layer):

        services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser>().AddEntityFrameworkStores<ApplicationDbContext>();
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Latest);

I now want to use this ApplicationDbContext class in the datalayer to keep code seperated. How would I best go about this? Injecting the class via constructor does not seem to work (Severity Code Description Project File Line Suppression State Error CS0246 The type or namespace name 'ApplicationDbContext' could not be found (are you missing a using directive or an assembly reference?))

namespace PizzaShop.Data.Repositories
{
   public class PizzaRepo : IPizzaRepo
   {
       private readonly ApplicationDbContext _context;

       public PizzaRepo(ApplicationDbContext context)
       {
          _context = context;
       }

       public async Task<int> AddEntityAsync(Pizza entity)
       {
           _context.Pizzas.Add(entity);
           return await _context.SaveChangesAsync();
       }
    //...
   }
}

Architecture: enter image description here

Upvotes: 1

Views: 731

Answers (2)

Derviş Kayımbaşıoğlu
Derviş Kayımbaşıoğlu

Reputation: 30545

Your ApplicationDbContext needs to be in the DataLayer.

References come from bottom to top which means from Presentation Layer References Business Layer References Data Layer. If you try to reference Presentation Layer in the Data Layer, cross reference problems occur. (it doesn't even makes sense).

As a result, move your ApplicationDbContext to where it belongs, which is the Data Layer and everything will be sorted out :)

Upvotes: 2

CodeCaster
CodeCaster

Reputation: 151588

If you want to keep all database-related stuff in the PizzaShop.Data project, then your ApplicationDbContext doesn't belong in your web project. It belongs in your PizzaShop.Data project.

You then reference your PizzaShop.Data project from the web project.

Upvotes: 5

Related Questions