问题描述
在angular 5+中使用自定义HttpInterceptors时,我收到以下奇怪的依赖项注入行为.
I am receiving the following strange dependency injection behavior when using custom HttpInterceptors in angular 5+.
以下简化的代码可以正常工作:
The following simplified code works fine:
export class AuthInterceptor implements HttpInterceptor {
constructor(private auth: AuthService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const token = this.auth.getToken();
return next.handle(req);
}
}
export class AuthService {
token: string;
constructor() {
console.log('AuthService.constructor');
}
}
但是......
AuthService
自身具有1个或多个依赖项时
When the AuthService
has 1 or more dependencies on its own e.g.
export class AuthService {
token: string;
constructor(private api: APIService) {
console.log('AuthService.constructor');
}
}
angular试图重复创建AuthService
的新实例,直到出现以下错误:
angular is trying to repeatedly create new instances of AuthService
until I receive the following errors:
日志显示AuthService.constructor
消息约400次
The log is displaying the AuthService.constructor
message ~400 times
和
和
然后我尝试使用Injector类注入服务-
I then tried injecting the service using the Injector class -
export class AuthService {
token: string;
api: APIService;
constructor(private injector: Injector) {
this.api = this.injector.get(APIService);
console.log('AuthService.constructor');
}
}
但出现相同的错误(最大调用堆栈大小).
but getting the same error (maximum call stack size).
APIService
是一个简单的服务,仅将HttpClient
注入其构造函数中.
The APIService
is a simple service that only injects the HttpClient
in its constructor.
@Injectable()
export class APIService {
constructor(private http: HttpClient) {}
}
最后,当我使用Injector
将AuthService
注入到Interceptor中时,错误消失了,但是AuthService被实例化了200多次:
Lastly, when I inject the AuthService
into the Interceptor using the Injector
, the error disappears but the AuthService is being instantiated 200+ times:
export class AuthInterceptor implements HttpInterceptor {
auth: AuthService;
constructor(private injector: Injector) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.auth = this.auth || this.injector.get(AuthService);
const token = this.auth.getToken();
return next.handle(req);
}
}
查看官方文档和其他示例,从技术上来说,将服务注入Http拦截器似乎是可行的.是否有任何限制或其他可能缺少的设置?
Looking at the official documentation and other example it seems as it is technically possible to inject services into the Http Interceptors. Is there any limitation or any other setup that might be missing?
推荐答案
因此,事实证明,如果您注入到Http Interceptor中的服务具有对HttpClient
的依赖关系,则会导致循环依赖关系.
So it turns out that if the service you inject into the Http Interceptor has a dependency on HttpClient
, this leads to a cyclic dependency.
由于我的AuthService
是所有不同逻辑的混合(登录/注销,路由用户,保存/加载令牌,进行api调用),因此我将拦截器所需的部分分为了自己的服务(仅用户)凭据和令牌),然后将其成功注入到拦截器中.
Since my AuthService
was a mix of all different logics (login/out, routing the user, saving/loading tokens, making api calls), I separated the part needed for the interceptors into its own service (just the user credentials & tokens) and now injecting it successfully into the Interceptor.
export class AuthInterceptor implements HttpInterceptor {
constructor(private credentials: CredentialsService) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const token = this.credentials.getToken();
const api_key = this.credentials.getApiKey();
}
}
export class CredentialsService {
token: string;
user: IUser;
constructor(private http: HttpClient) {
this.loadCredentialsFromStorage();
}
}
这似乎工作正常.希望这对某人有帮助.
This seems to work fine. Hope this helps someone.
这篇关于注入服务时出现Angular 5 Http拦截器错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!