使用ngx-signalR-hubservice遇NullInjectorError:无HubService提供者
你遇到了这样的依赖注入错误:
ERROR Error: StaticInjectorError(AppModule)[SignUpComponent -> HubService]:
StaticInjectorError(Platform: core)[SignUpComponent -> HubService]:
NullInjectorError: No provider for HubService!
at NullInjector.push../node_modules/@angular/core/fesm5/core.js.NullInjector.get (core.js:979)
虽然你已经在AppModule的providers里添加了HubService,但这并不是ngx-signalR-hubservice库的正确注册方式。我来帮你快速修复这个问题:
问题根源
ngx-signalR-hubservice需要通过模块导入的方式完成全局配置,直接把HubService放进providers数组会导致Angular的依赖注入系统无法正确初始化它的实例。
分步解决方案
1. 修正AppModule的配置
首先导入HubServiceModule,并在imports中用forRoot()方法配置全局SignalR参数,同时移除providers中的HubService:
import { NgModule } from '@angular/core'; import { HubServiceModule } from 'ngx-signalr-hubservice'; import { BrowserModule } from '@angular/platform-browser'; // 务必添加这个基础模块 @NgModule({ declarations: [ AppComponent, SignUpComponent, LogInComponent ], imports: [ BrowserModule, HubServiceModule.forRoot({ url: 'http://localhost:10476/signalr' // 全局配置SignalR服务地址 }) ], providers: [], // 这里不再需要HubService bootstrap: [AppComponent] }) export class AppModule {}
2. 优化UserConnectionServiceService
既然已经在全局配置了连接地址,就不需要在服务里手动调用connect()了,库会自动管理连接:
import { Injectable } from '@angular/core'; import { HubService, Hub, HubSubscription, HubWrapper } from 'ngx-signalr-hubservice'; @Injectable({providedIn: 'root'}) @Hub({hubName: 'DALHub'}) export class UserConnectionServiceService { private hubWrapper: HubWrapper; constructor(private hub: HubService) { this.hubWrapper = this.hub.register(this); // 移除手动connect的代码,全局配置会自动处理连接 } async SaveKey() { await this.hubWrapper.invoke('SaveKey', 'yedidya', 'kfiry'); console.log('awesome'); } @HubSubscription() OK() { console.log('GOT IT'); } }
3. 组件调用无需修改
你的SignUpComponent代码是没问题的,因为UserConnectionServiceService用了providedIn: 'root',Angular会自动为它创建实例并注入。
为什么这样改?
HubServiceModule.forRoot()会在应用启动时正确注册HubService的提供者,确保依赖注入系统能找到它的实例。- 全局配置连接地址后,避免了在每个服务中重复配置连接,库会自动处理连接的建立、重连等逻辑。
完成这些修改后,重新运行ng serve,应该就能解决这个注入错误了。
内容的提问来源于stack exchange,提问作者Yedidya kfir

