1
votes

In my ASP.NET Core MVC site, I have a SignalR hub that has my DbContext injected into the constructor. The hub pulls data from the database and send it to a kendo ui grid for the user to view. This data is filtered in that hub on which group is selected (stored in the database).

The group selection is done outside the context of the hub. When I change the users selected group the page reloads to update various UI elements. When the signalr hub is then called, the selected group is still set as what it was prior to the change. After digging for a bit I came across this issue on the signalr github. What I understand is because the hub is transient, the DbContext is as well and since the hub is long running the DbContext is never updated.

Is there a simple way around this while still dependency injecting the DbContext or do I need to create and dispose a new context for every call? If so what is the best way to go about doing that and still pass the connection string from the appsettings.json?

EDIT

I am currently using Microsoft.AspNetCore.SignalR.Server and not the new Microsoft.AspNetCore.SignalR library.

1
In a modern signalr core scoped services and in particular DbContext can be used like in asp.net core controllers. See this answerAlbertK

1 Answers

3
votes

The only way I could get around this issue with Microsoft.AspNetCore.SignalR.Server was to add a DbContextOptionsBuilder<T> singleton to the the ConfigureServices method in Startup.cs and then call that in a using(...) in the hub. While I feel this is a dirty way around the issue, I also believe it is the only way around the issue. Microsoft recently deprecated SignalR-Server and are moving to a new code base at SignalR. Hopefully this issue will be addressed in their new version.

Startup.cs

DbContextOptionsBuilder<PortalDbContext> builder = new DbContextOptionsBuilder<PortalDbContext>();
builder.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
services.AddSingleton(builder.Options);

Hub Classes

using (PortalDbContext dbContext = new PortalDbContext(_dbContextOptions))
{
    ...
}