Using Entity Framework Core to process Azure Service Messages in ASP.NET Core

This article shows how to use Entity Framework Core together with an Azure Service Bus receiver in ASP.NET Core. This message handler is a singleton and so requires that an Entity Framework Core context inside this singleton is not registered as a scoped service but created and disposed for each message event.

Code: https://github.com/damienbod/AspNetCoreServiceBus

Posts in this series:

History

  • 2024-06-30 Updated packages, Azure function
  • 2021-05-18 Updated .NET, Azure Service Bus SDK

Processing the Azure Service Bus Messages

The ProcessData class is used to handle the messages in the ASP.NET Core application. The service uses an Entity Framework Core context to save the required data to a database.

using AspNetCoreServiceBusApi2.Model;
using ServiceBusMessaging;

namespace AspNetCoreServiceBusApi2;

public class ProcessData : IProcessData
{
    private readonly IConfiguration _configuration;

    public ProcessData(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    public async Task Process(MyPayload myPayload)
    {
        var connection = _configuration.GetConnectionString("DefaultConnection");
        if (connection == null) throw new ArgumentNullException(nameof(connection));

        using var payloadMessageContext = new PayloadMessageContext(connection);
        await payloadMessageContext.AddAsync(new Payload
        {
            Name = myPayload.Name,
            Goals = myPayload.Goals,
            Created = DateTime.UtcNow
        });

        await payloadMessageContext.SaveChangesAsync();
    }
}

The services used to consume the Azure Service Bus are registered to the IoC (Inversion of Control) as singletons. Due to this, only singletons or transient services can be used. If we use the context as a singleton, we will end up having connection and pooling problems with the database.

services.AddSingleton<IServiceBusConsumer, ServiceBusConsumer>(); services.AddSingleton<IServiceBusTopicSubscription, ServiceBusTopicSubscription>(); services.AddSingleton<IProcessData, ProcessData>();

A PayloadMessageContext Entity Framework Core context was created for the Azure Service Bus message handling.

using Microsoft.EntityFrameworkCore;

namespace AspNetCoreServiceBusApi2.Model;

public class PayloadMessageContext : DbContext
{
    private readonly string _connectionString;

    public DbSet<Payload> Payloads { get; set; }

    public PayloadMessageContext(string connectionString)
    {
        _connectionString = connectionString;
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite(_connectionString);
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<Payload>().Property(n => n.Id).ValueGeneratedOnAdd();
        builder.Entity<Payload>().HasKey(m => m.Id);
        base.OnModelCreating(builder);
    }
}

The required NuGet packages were added to the project. This demo uses SQLite. Microsoft.EntityFrameworkCore.Sqlite

The service is then added in the Startup class as a singleton. The Entity Framework Core context used for the messaging is not registered here, because it is used inside the singleton instance and we do not want a context which is a singleton, because it will have problems with the database connections, and pooling. Instead a new context is created inside the service for each message event and disposed after. If you have a lot of messages, this would need to be optimized.

Now when the ASP.NET Core application receives messages, the singleton service context handles this messages, and saves the data to a database.

Links:

https://docs.microsoft.com/en-us/azure/service-bus-messaging/

https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-dotnet-get-started-with-queues

https://www.nuget.org/packages/Microsoft.Azure.ServiceBus

Azure Service Bus Topologies

https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/multi-container-microservice-net-applications/integration-event-based-microservice-communications

Always subscribe to Dead-lettered messages when using an Azure Service Bus

https://ml-software.ch/posts/stripe-api-with-asp-net-core-part-3

One comment

  1. Rob Martin's avatar
    Rob Martin · · Reply

    RE: “If you have a lot of messages, this would need to be optimized”, could you please suggest a strategy.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.