1

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

  • Is this error occurring in design time or run time? Are the layers separated in different assemblies or is it just one application? Passing the context in the constructor is def the way to go, so this should work. – ngruson Dec 17 '18 at 13:57
  • Hi. The error is occurring at design time. The layers are all included within the same solution file, each contained within a single project. I have included a screenshot of the architecture. – Michiel Wouters Dec 17 '18 at 14:41

2 Answers2

5

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.

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
2

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 :)

Derviş Kayımbaşıoğlu
  • 28,492
  • 4
  • 50
  • 72