You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 18为APP_INITIALIZER添加依赖时遇错误的解决咨询

Angular 18中配置APP_INITIALIZER依赖服务的问题解决

问题场景

我在Angular 18中尝试配置APP_INITIALIZER,使其依赖JwtService和AuthService,相关代码如下:

初始化函数与应用配置

export function initAuth(jwtService: JwtService, authService: AuthService) {
  return () => (jwtService.getToken() ? authService.getCurrentUser() : EMPTY);
}

export const appConfig: ApplicationConfig = {
  providers: [
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(routes),
    provideHttpClient(withInterceptors([jwtInterceptor])),
    {
      provide: APP_INITIALIZER,
      useFactory: initAuth,
      deps: [JwtService, AuthService, HttpClient],
      multi: true,
    },
  ],
};

JwtService代码

@Injectable({ providedIn: 'root' })
export class JwtService {
  getToken(): string {
    return window.localStorage['jwtToken'];
  }

  setToken(token: string): void {
    window.localStorage['jwtToken'] = token;
  }

  destroyToken(): void {
    window.localStorage.removeItem('jwtToken');
  }
}

AuthService代码

@Injectable({ providedIn: 'root' })
export class AuthService {
  private apiUrl = environment.apiUrl + '/Auth';
  private http = inject(HttpClient);
  private router = inject(Router);

  private _loggedInUserSubject = new BehaviorSubject<User | null>(null);
  currentUser$ = this._loggedInUserSubject.asObservable();
  isAuthenticated$ = this.currentUser$.pipe(map((u) => u !== null));

  constructor(private jwtService: JwtService) {}

  register(credentials: RegisterCredentials): Observable<boolean> {
    return this.http
      .post<{ username: string }>(this.apiUrl + '/register', credentials)
      .pipe(map((user) => user.username === credentials.username));
  }

  login(credentials: LoginCredentials): Observable<User> {
    return this.http
      .post<User>(this.apiUrl + '/login', credentials)
      .pipe(tap((user) => this.setAuth(user)));
  }

  logout() {
    this.purgeAuth();
    this.router.navigate(['']);
  }

  getCurrentUser() {
    return this.http.get<User>(this.apiUrl).pipe(tap((u) => this.setAuth(u)));
  }

  private setAuth(user: User) {
    this._loggedInUserSubject.next(user);
    this.jwtService.setToken(user.token);
  }

  private purgeAuth() {
    this._loggedInUserSubject.next(null);
    this.jwtService.destroyToken();
  }
}

错误情况

  1. 首次运行应用时出现错误:
    NullInjectorError: No provider for JwtService!

  2. 尝试将JwtService和AuthService加入providers后,出现新错误:
    Invalid provider for the NgModule 'ApplicationConfig'

排查后确认是AuthService导致的“无效提供者”错误。

解决方案

问题出在三个核心点,逐一修正即可:

1. 统一服务注入方式

AuthService同时使用了构造函数注入(jwtService)和inject()函数(HttpClient、Router),这种混合注入方式在Angular 18独立应用配置中会引发提供者异常。需统一为一种注入方式,这里推荐用构造函数注入:

@Injectable({ providedIn: 'root' })
export class AuthService {
  private apiUrl = environment.apiUrl + '/Auth';

  private _loggedInUserSubject = new BehaviorSubject<User | null>(null);
  currentUser$ = this._loggedInUserSubject.asObservable();
  isAuthenticated$ = this.currentUser$.pipe(map((u) => u !== null));

  constructor(
    private jwtService: JwtService,
    private http: HttpClient,
    private router: Router
  ) {}

  // 其余方法保持不变
}

2. 移除重复注册的服务

JwtService和AuthService已经配置了providedIn: 'root',Angular会自动将它们注册为根提供者,手动添加到appConfig.providers会导致重复注册,引发错误。因此要从providers数组中移除这两个服务。

3. 精简APP_INITIALIZER的依赖项

initAuth函数只直接依赖JwtService和AuthService,HttpClient不需要出现在deps中——Angular会自动解析AuthService的依赖链。修改后的APP_INITIALIZER配置:

{
  provide: APP_INITIALIZER,
  useFactory: initAuth,
  deps: [JwtService, AuthService],
  multi: true,
}

最终的appConfig:

export const appConfig: ApplicationConfig = {
  providers: [
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(routes),
    provideHttpClient(withInterceptors([jwtInterceptor])),
    {
      provide: APP_INITIALIZER,
      useFactory: initAuth,
      deps: [JwtService, AuthService],
      multi: true,
    },
  ],
};

总结

  • 避免在同一个服务中混合使用构造函数注入和inject()函数;
  • 无需手动添加providedIn: 'root'的服务到应用配置的providers数组;
  • 精简APP_INITIALIZER的deps,只保留直接依赖的服务。

内容的提问来源于stack exchange,提问作者M. Kel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 18:55:10