This example demonstrates how to add an Entity Framework Core database context as a service using Dependency Injection (a form of Inversion of Control) in ASP.Net MVC Core 2, with an example of referencing the context from an MVC Controller. This example uses a connection string stored in the Development configuration file appsettings.Development.json.

Some notes:

  • Microsoft recommends using the Repository pattern to further abstract the database access layer, in which case we would use the interface IProductsDb in the Dependency Injection instead of the concrete class ProductsDb. However, I’ve concluded after some research that the Repository Pattern is an unnecessary abstraction when using Entity Framework Core or even Entity Framework 6. Read more about that here.
  • The code below only works when you have the Microsoft.EntityFrameworkCore NuGet package installed. If you are using .Net Core 3, you may also need to have the Microsoft.EntityFrameworkCore.SqlServer NuGet package installed.
  • These instructions are based on using Entity Framework Core in ASP.Net MVC Core 2. If you are using Entity Framework 6, the process is slightly different. Check out these instructions.

While some instructions suggest using services.AddScoped() to inject a DbContext as a dependency, services.AddDbContext() provides the same service lifetime (lifetime of a single request) and also gives you the ability to configure the service in the function call. More details about the advantages of using services.AddDbContext() over services.AddScoped() can be found in this StackOverflow answer.

ConfigureServices method in Startup.cs:

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services) {

    string connectionString = Configuration.GetConnectionString("DefaultConnection");
    services.AddDbContext<ProductsDb>(options => options.UseSqlServer(connectionString));
    services.Configure<CookiePolicyOptions>(options => {
        // This lambda determines whether user consent for non-essential cookies is needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Controller CategoryController.cs:

public class CategoryController : Controller {

    private readonly ProductsDb context;

    public CategoryController (ProductsDb context) {
        this.context = context;
    }

    public IActionResult Index() {
        List<Category> AllCategories = context.Categories.ToList();
        return View(AllCategories);
    }

}

Connection String in appsettings.Development.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  },
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=HumanResources;Trusted_Connection=True"
  }
}