Angular 16自定义MsalInterceptor继承@Injectable报错求助
解决Angular 16升级后自定义MsalInterceptor的依赖注入错误
升级Angular至v16后,自定义拦截器继承MsalInterceptor时会触发如下错误:
可注入类CustomMsalInterceptor继承自MsalInterceptor的构造函数,但后者本身没有Angular装饰器,依赖注入无法解析MsalInterceptor构造函数的参数。
这是因为Angular 16收紧了依赖注入规则:当继承的父类未添加@Injectable装饰器时,框架无法自动解析父类构造函数的参数,必须在子类中显式声明构造函数并传递依赖。
解决方案:为CustomMsalInterceptor添加显式构造函数
由于MsalInterceptor是@azure/msal-angular提供的第三方类,无法直接为其添加@Injectable装饰器,因此最优方案是修改自定义拦截器,显式注入父类所需的全部依赖并传递给super:
修改后的CustomMsalInterceptor代码如下:
import { Injectable, Inject } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpContextToken, HttpHeaders, } from '@angular/common/http'; import { Observable } from 'rxjs'; import { MsalInterceptor, MsalInterceptorConfiguration } from '@azure/msal-angular'; import { MsalService } from './msal.service'; import { Location } from '@angular/common'; import { MsalBroadcastService } from './msal.broadcast.service'; import { DOCUMENT } from '@angular/common'; export const BYPASS_MSAL = new HttpContextToken(() => false); @Injectable() export class CustomMsalInterceptor extends MsalInterceptor implements HttpInterceptor { // 显式构造函数,注入父类所需所有依赖 constructor( @Inject('MSAL_INTERCEPTOR_CONFIG') msalInterceptorConfig: MsalInterceptorConfiguration, authService: MsalService, location: Location, msalBroadcastService: MsalBroadcastService, @Inject(DOCUMENT) document?: any ) { super(msalInterceptorConfig, authService, location, msalBroadcastService, document); } intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { if (request.context.get(BYPASS_MSAL)) { if (sessionStorage.getItem('token')) { request = request.clone({ headers: new HttpHeaders({ Authorization: 'Bearer ' + sessionStorage.getItem('token'), }), }); } return next.handle(request); } return super.intercept(request, next); } }
说明
- 构造函数需注入
MsalInterceptor的所有参数:MsalInterceptorConfiguration(通过@Inject('MSAL_INTERCEPTOR_CONFIG')注入,这是MSAL Angular的官方注入令牌)、MsalService、Location、MsalBroadcastService、DOCUMENT(可选参数)。 - 通过
super()将这些依赖传递给父类构造函数,确保Angular能正确解析所有依赖项。 - 该方案无需修改第三方库代码,完全符合Angular 16的DI规则,是最稳妥的解决方式。
内容的提问来源于stack exchange,提问作者Lesmoto 22 Mowa
相关产品推荐
相关产品推荐

