Home > Net >  .NET 6 IHubContext Dependency Injection
.NET 6 IHubContext Dependency Injection

Time:03-18

I'm working on a simple .NET 6 application to enable data update notifications in our front-end application. I've built something similar in .NET 5 before, but I'm running across a DI issue that's got me stumped. In 5, all hubs that were mapped automatically have an IHubContext that is set up in the container for them as well. That doesn't appear to be the case anymore in 6.

System.InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNet.SignalR.IHubContext`1[SignalRNotifications.Hubs.NotificationHub]' while attempting to activate 'SignalRNotifications.Controllers.NotificationController'.

The new non-startup DI in 6 looks weird to me, but I'm just not seeing anything available that says how to fix it. Any suggestions on how to get an IHubContext to inject into my controller?

Thanks!

Update: Here is some pertinent code:

using Microsoft.AspNetCore.Builder;
using SignalRNotifications.Hubs;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
builder.Services.AddSignalR().AddAzureSignalR();


var app = builder.Build();

// Configure the HTTP request pipeline.
app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.UseRouting();
app.UseEndpoints(endpoints =>
{
    endpoints.MapHub<NotificationHub>("/NotificationHub");
});

app.Run();

Dependency injection is done in the controller in the most predictable of ways:

namespace SignalRNotifications.Controllers
{
    [AllowAnonymous]
    [Route("api/[controller]")]
    [ApiController]
    public class NotificationController : ControllerBase
    {
        private readonly IHubContext<NotificationHub> _notificationContext;

        public NotificationController(IHubContext<NotificationHub> notificationContext)
        {
            _notificationContext = notificationContext;
        }

CodePudding user response:

If you boil this down to the minimal amount of code necessary, it does correctly inject a hub context.

Program.cs

using HelloAspNetCoreSix;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddSignalR();
var app = builder.Build();

app.MapControllers();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
    endpoints.MapHub<NotificationHub>("/NotificationHub");
});

app.Run();

Hub

using Microsoft.AspNetCore.SignalR;

namespace HelloAspNetCoreSix
{
    public class NotificationHub : Hub
    {
    }
}

Controller

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;

namespace HelloAspNetCoreSix
{
    [ApiController]
    [Route("api/[controller]")]
    public class NotificationController : ControllerBase
    {
        readonly IHubContext<NotificationHub> _notificationContext;

        public NotificationController(IHubContext<NotificationHub> notificationContext)
        {
            _notificationContext = notificationContext;
        }

        public IActionResult Index()
        {
            return Ok("HubContext: "   _notificationContext.ToString());
        }
    }
}

Try it yourself. Either you've added something that broke it (nothing seemed obvious in the code you've shown) or perhaps you've got some sort of build issue where you're not running the code that you think you're running.

Again, this goes to show the important of creating a minimal reproducible example. You either start from the ground up and keep adding things in until it breaks, or you remove everything you can from the app until you've found the smallest possible remainder that still reproduces the issue.

CodePudding user response:

builder.services.AddSingleton<IHubContext<ChatHub>>(hubContext);

add this on program on builder.services

microsoft doc

  • Related