我有以下构造函数:

constructor(env: Env, private logger: Logger,
  @Inject(MockEndpoints.TOKEN) @Optional()
  private endpoints: MockEndpoints[]) {
    // ...
}

它与jit编译器一起工作。
但如果启用了aot编译器,则会产生生成错误:
ERROR in : Can't resolve all parameters for MockBackendInterceptor in /path/mock-backend.interceptor.ts: ([object Object], [object Object], ?).
令牌对象定义如下:
export interface MockEndpoints {
  handle(req: HttpRequest<any>): HttpResponse<any>;
}

export namespace MockEndpoints {
  export const TOKEN: InjectionToken<MockEndpoints[]> =
    new InjectionToken<MockEndpoints[]>('MockEndpoints');
}

我确信这完全是由医生推荐的。
有什么暗示吗?;)
编辑(作为对Gunter评论的回应):
端点在同一模块中注册:
@NgModule({
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: MockBackendInterceptor, multi: true },
    { provide: MockEndpoints.TOKEN, useClass: MockBackupService, multi: true },
    { provide: MockEndpoints.TOKEN, useClass: MockConfigurationService, multi: true }
  ]
})
export class MockBackendModule { }

最佳答案

最后我找到了原因。
非常感谢用户yurzuiGünter Zöchbauer的评论,这些评论有助于发现问题。
解决方案
如果(并且仅当)令牌常量在命名空间内声明,
InjectionToken的参数化类型(例如,MockEndpoints在这种情况下)不能是一个接口。所以把它改成一个抽象类就足够了。

export abstract class MockEndpoints {
  handle(req: HttpRequest<any>): HttpResponse<any>;
}

export namespace MockEndpoints {
  export const TOKEN: InjectionToken<MockEndpoints[]> =
    new InjectionToken<MockEndpoints[]>('MockEndpoints');
}

从名称空间中提取令牌常量甚至更简单。
export interface MockEndpoint {
  handle(req: HttpRequest<any>): HttpResponse<any>;
}

export const MOCK_ENDPOINT = new InjectionToken<MockEndpoint[]>('MockEndpoints');

请注意,名称空间名称与接口名称相同(在本例中,两个名称都MockEndpoints)这一事实没有任何意义。当在名称空间中声明了令牌常量时,不同的名称不适用于接口作为参数化类型。
当然,它也使用纯字符串标记,而不是使用InjectionToken接口。
此行为仅在使用AOT编译时发生。使用jit,两种情况下都没有问题。

关于angular - 具有用户定义的InjectionToken的DI在启用AOT时不起作用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48341592/

10-09 23:42