如何正确配置与SignalR NotificationHub交互的服务?依赖注入疑问
问题:SignalR Hub的Clients属性为null,依赖注入配置是否正确?
我正尝试创建一个与名为NotificationHub的SignalR Hub交互的服务,当前配置下Hub中的Clients属性为null。请问这样的依赖注入配置方式是否正确,能否实现服务与Hub的正常交互?
Notification Hub 代码
public interface INotificationHub { Task Send(Notification notification); }
public class NotificationHub : Hub, INotificationHub { public async Task Send(Notification notification) { // Clients is null here await Clients.All.SendAsync(notification.Type, notification); } }
Notification Service 代码
public interface INotificationService { Task SendNotificationToAll(Notification notification); }
public class NotificationService : INotificationService { private readonly INotificationHub _hubContext; public NotificationService(INotificationHub hubContext) { _hubContext = hubContext; } public async Task SendNotificationToAll(Notification notification) { await _hubContext.Send(...); } }
控制器调用代码
public class SomeController : Controller { private readonly INotificationService _notificationService; public SomeController (..., INotificationService notificationService) { _notificationService = notificationService; } [HttpPost, Route("notification")] public async Task<IActionResult> Notification() { _notificationService.SendNotificationToAll(notification1); } }
问题分析与解决方案
你的依赖注入配置不正确,这就是Clients属性为null的直接原因。SignalR的Hub实例由框架自行管理,不会通过依赖注入容器创建,直接注入INotificationHub会得到一个未完成Hub初始化流程的实例——框架不会为手动创建的Hub实例初始化Clients等核心属性。
正确的做法是注入IHubContext<NotificationHub>,这是SignalR官方提供的、用于在Hub外部与Hub交互的标准方式:
修改后的NotificationService
public class NotificationService : INotificationService { private readonly IHubContext<NotificationHub> _hubContext; public NotificationService(IHubContext<NotificationHub> hubContext) { _hubContext = hubContext; } public async Task SendNotificationToAll(Notification notification) { // 直接通过HubContext调用客户端方法 await _hubContext.Clients.All.SendAsync(notification.Type, notification); } }
调整说明
- 无需通过
INotificationHub接口注入Hub实例,IHubContext<NotificationHub>已能完成所有与客户端通信的操作。 - 若希望保留
INotificationHub封装Hub方法,可修改Hub类依赖IHubContext(非必需操作):
public class NotificationHub : Hub, INotificationHub { private readonly IHubContext<NotificationHub> _hubContext; public NotificationHub(IHubContext<NotificationHub> hubContext) { _hubContext = hubContext; } public async Task Send(Notification notification) { await _hubContext.Clients.All.SendAsync(notification.Type, notification); } }
但即使这样,外部服务依然应该注入IHubContext<NotificationHub>,而非INotificationHub。
依赖注入注册
确保在Program.cs中正确注册SignalR与服务:
builder.Services.AddSignalR(); builder.Services.AddScoped<INotificationService, NotificationService>();
同时配置Hub的Endpoint:
app.MapHub<NotificationHub>("/notificationHub");
完成上述修改后,服务即可正常与SignalR Hub交互,Clients属性也不会再为null。
内容的提问来源于stack exchange,提问作者Scott
相关产品推荐
相关产品推荐

