Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resolve EF7 current database context in ASP NET 5 out of the controller?

I want to get one context per request in ASP NET 5/EF 7 app for use it in some methods (not in controller).

Unfortunately I did not find the answer in the documentation ASP.NET vNext template and examples aspnet/MusicStore

like image 293
Andrey V Drevin Avatar asked Oct 09 '15 11:10

Andrey V Drevin


People also ask

How do I update my Entity Framework model in .NET core?

Right-click anywhere on the design surface, and select Update Model from Database... In the Update Wizard, select the Refresh tab and select your table then click Finish button. This is only possible up until EF6 and lower - and not the core variant, as requested.

Is DbContext scoped?

This example registers a DbContext subclass called ApplicationDbContext as a scoped service in the ASP.NET Core application service provider (a.k.a. the dependency injection container). The context is configured to use the SQL Server database provider and will read the connection string from ASP.NET Core configuration.

What is a DbContext class?

A DbContext instance represents a combination of the Unit Of Work and Repository patterns such that it can be used to query from a database and group together changes that will then be written back to the store as a unit. DbContext is conceptually similar to ObjectContext.

How do you add a razor page in Entity Framework crud?

In Solution Explorer, right-click the Pages/Students folder and select Add > New Scaffolded Item. In the Add New Scaffold Item dialog: In the left tab, select Installed > Common > Razor Pages. Select Razor Pages using Entity Framework (CRUD) > ADD.


1 Answers

You may use some methods for achieving this purpose.

Using .AddDbContext<ApplicationDbContext>(); method for registering ApplicationDbContext in Dependency Injection system (in ConfigureServices() method), leads to the fact that it registered as Scoped dependence(or in another words "per request"). Thereby you only need get it from Dependency Injection system.

  1. Add your dbContext as parameter of constructor method your class (in which you will use dbContext). Then you have to get this class using Dependency Injection system, e.g added it as parameter of controller's constructor.

    public class HabitsController : Controller
    {
        public HabitsController(HabitService habitService)
        {
    
        }
    }
    
    public class HabitService
    {
        private GetHabitsContext _dbContext;
    
        public HabitService(GetHabitsContext dbContext)
        {
            _dbContext = dbContext;
        }
    }
    
  2. But if you don't want to use constructor injection for getting context, you can get necessary dependenses using GetService() method (but you need in ServiceProvider instance for that, in example below, i'am getting it through constructor injection too).

    using Microsoft.Framework.DependencyInjection; // for beta 6 and below
    using Microsoft.Extensions.DependencyInjection; // for beta 7 and above
    public class HabitService
    {
        private IServiceProvider _serviceProvider;
    
        public HabitService(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
        }
    
        public GetHabit()
        {
             var dbcontext = _serviceProvider.GetService<ApplicationDbContext>();
        }
    }
    
  3. In first method, we can get HabitService through GetService() method too (not through the constructor injection).

    using Microsoft.Framework.DependencyInjection; // for beta 6 and below
    using Microsoft.Extensions.DependencyInjection; // for beta 7 and above
    
    public class HabitsController : Controller
    {
        public HabitsController(IServiceProvider serviceProvider)
        {
           var habitService= serviceProvider.GetService<HabitService>();
        }
    }
    
    public class HabitService
    {
        private GetHabitsContext _dbContext;
    
        public HabitService(GetHabitsContext dbContext)
        {
            _dbContext = dbContext;
        }
    }
    

Thanks Tseng for remark:

I should be noted, that it's a pretty bad practice to inject the container into your objects. The container should only be referenced from the composition root and certain type of factories (which are implemented on application level, and not in the domain/business layer)


dbContext in HabitsController and _dbContext in HabitService are different contexts!

I checked, this is the same context.

like image 95
Stas Boyarincev Avatar answered Oct 07 '22 00:10

Stas Boyarincev