Using DbContext in the IHostedService-Entity framework

Today in this article we shall see how to DI (Dependency injection) to use DbContext in the IHostedService-Entity framework(created using ORM framework like Entity framework Core)

If you are creating long-running services using IHostedService directly or using Base class BackgroundService then you might need to DI multiple other services like DbContext.

  • As a good practice, EFCore DBContext should be set as a scoped instance. In fact, using AddDBContext lets you add a scoped instance of DBContext to be the default.

  • While scoped service instances are created once per request it is often recommended they are resolved using a scoped instance of services that use them.

With the above basic understanding to use services inside of hosted services, one can use scoped instances. The below example explained details about two approaches to achieve this.

By doing this DBContext will be used with the lifetime configuration set up originally. This will also make sure Singletone instances are not created for the given services.

Resolving other Services?

If you have any other services apart from DBContext, you can very much follow any of the below two approaches discussed.

Approach 1- Using ServiceScopeFactory to resolve scope instances

We shall DI IServiceScopeFactory using constructor injection to create and resolve scope DBContext instances as below,

 class TheCodeBuzzConsumer : BackgroundService
    {
        private readonly ILogger<TheCodeBuzzConsumer> _logger;
        private readonly EmployeeContext _employeeContext;

        public TheCodeBuzzConsumer(ILogger<TheCodeBuzzConsumer> logger, IServiceScopeFactory factory)
        {
            _logger = logger;
            _employeeContext = factory.CreateScope().ServiceProvider.GetRequiredService<EmployeeContext>();
        }

Above BackgroundService is the Base class for implementing IHostedService.

The above code lets you create Scoped instance of EmployeeContext and is able to work with the Database easily.

EFCore DbContext in IHostedServiceDbContext in the IHostedService Entity framework

Approach 2- Using IServiceProvider to resolve scope DBContext instances

We shall DI IServiceProvider using constructor injection to create and resolve scope DBContext instances as below,

class TheCodeBuzzConsumer : BackgroundService
    {
        private readonly ILogger<TheCodeBuzzConsumer> _logger;
        private readonly EmployeeContext _employeeContext;
        public TheCodeBuzzConsumer(ILogger<TheCodeBuzzConsumer> logger, IServiceProvider serviceProvider)
        {
            _logger = logger;
            _employeeContext = serviceProvider.CreateScope().ServiceProvider.GetRequiredService<EmployeeContext>();
        }

References:

Either way, as discussed above you shall be able to resolve the DBContext within scope instances.

Do you have any comments or ideas or any better suggestions to share?

Please sound off your comments below.

Happy Coding !!



Please bookmark this page and share it with your friends. Please Subscribe to the blog to receive notifications on freshly published(2024) best practices and guidelines for software design and development.



3 thoughts on “Using DbContext in the IHostedService-Entity framework

  1. Your post steered me in the right direction, but in itself, was not enough. By using the factory in the constructor, the context is still always the same. I ended up having to use the factory in the overridden ExecuteAsync method, because the constructor is only ever called once, but the loop in ExecuteAsync is executed multiple times. I’m using the same structure as your other article, https://thecodebuzz.com/create-asp-net-core-app-as-windows-service-listen-event-message/.

Leave a Reply

Your email address will not be published. Required fields are marked *