Home > other >  How to inject service for SignalR hub
How to inject service for SignalR hub

Time:01-02

In my ASP.NET Core 7 MVC application, in startup.cs hub service is injected like this:

public void ConfigureServices(IServiceCollection services)
{
    // ...
    services.AddScoped<IHubContext<OstupultHub>>();
}

Running the application throws an exception

System.ArgumentException HResult=0x80070057
Cannot instantiate implementation type 'Microsoft.AspNetCore.SignalR.IHubContext1[Store.Hubs.OstupultHub]' for service type 'Microsoft.AspNetCore.SignalR.IHubContext1[Store.Hubs.OstupultHub]'

Source=Microsoft.Extensions.DependencyInjection
StackTrace:
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.Populate() in /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteFactory.cs:line 68 ...

How to fix this so that hub can be used in MVC controller constructor like

public MyController(IHubContext<OstupultHub> hubContext ) { ...

Hub class is defined as

using Microsoft.AspNetCore.SignalR;
namespace Store.Hubs;

public class OstupultHub : Hub
{  ... 
}

According to

https://learn.microsoft.com/en-us/aspnet/core/signalr/hubcontext?view=aspnetcore-7.0

it should work.

Currently I'm using in controller constructor IServiceProvider

public OstupultController(IServiceProvider _provider )
  {
    provider = _provider;
  }

and then in controller

  public async Task<ContentResult> ReceiveLogFile()
  {
    var pultHub = provider.GetRequiredService<IHubContext<OstupultHub>>();
    await pultHub.Clients.All.SendAsync("sendLogFileMessage");
    return new ContentResult() { Content ="sent" };
  }

Looking for use service directly like other servies.

CodePudding user response:

service is injected as services.AddScoped<IHubContext<OstupultHub>>();

AFAIK you don't need to register hubs this way. Just call services.AddSignalR() in the ConfigureServices and MapHub<OstupultHub>(...); in the Configure.

CodePudding user response:

In Program.cs, like what Guru said using services.AddSignalR(); and

app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Privacy}/{id?}");
                endpoints.MapHub<ChatHub>("/chatHub");
            });

In my controller:

public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;
        private readonly IHubContext<ChatHub> _hubContext;


        public HomeController(ILogger<HomeController> logger, IHubContext<ChatHub> hubContext)
        {
            _logger = logger;
            _hubContext = hubContext;
        }

        public IActionResult IndexAsync()
        {
            return View();
        }

        public async Task getInfo() {
            await _hubContext.Clients.All.SendAsync("Notify", $"Home page loaded at: {DateTime.Now}");
        }
  • Related