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

asp.net-core entity-framework-core

Question

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

Accepted Answer

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.



Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why