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

Angular 12 外部库依赖注入问题:指令注入服务失败

Angular跨模块注入外部库指令服务失败问题

问题场景

需要为外部库的指令注入服务,该指令会在多个应用及每个应用的不同模块中复用,且每个模块需注入各自对应的服务。

已在库模块中创建注入令牌SERVICE_ADAPTER和服务接口ServiceAdapter,主应用的使用模块导入后通过useExisting结合该令牌提供服务,指令构造函数中使用@Inject(SERVICE_ADAPTER)注入。但加载使用该指令的组件时,持续出现以下错误:

NullInjectorError: R3InjectorError(DashboardModule)[InjectionToken service token -> InjectionToken service token]


相关代码

库模块代码

import { Directive } from './directives/directive.directive';

@NgModule({
   exports: [
      ...,
      Directive
   ],
   imports: [CommonModule,...],
   declarations: [
      ...,
       Directive
   ]
})
export class LibraryModule {
  }

export const SERVICE_ADAPTER: InjectionToken<ServiceAdapter> =
  new InjectionToken('service token');

export interface ServiceAdapter {
  a(): void
}

库中指令代码

import { Directive, ElementRef, EventEmitter, HostListener, Inject, Input, Output } from '@angular/core';
import { ServiceAdapter, SERVICE_ADAPTER } from '../library.module';

@Directive({
  selector: '[myDirective]'
})
export class Directive {
  @Input() field: string = ''
  @Input() method: string = ''
  

  constructor(private el: ElementRef, @Inject(SERVICE_ADAPTER) protected service: ServiceAdapter) {}

  @HostListener('keyup', ['$event'])
  keyup(event: any) {
        // 业务逻辑
  }
}

使用模块代码

...
import { LibraryModule,SERVICE_ADAPTER } from 'Library...';

@NgModule({
  providers: [
      { provide: SERVICE_ADAPTER, useExisting: ProjectsService }
    ],
   declarations: [
     ...
   ],
   imports: [
      LibraryModule,
   ]
})
export class ProjectsModule {

}

问题排查与解决

1. 确保目标服务已被正确提供

useExisting依赖目标服务(此处为ProjectsService)本身已在当前模块或上层注入器中注册。如果ProjectsService未被声明为提供者,Angular无法找到它来关联注入令牌。修改使用模块:

@NgModule({
  providers: [
    ProjectsService, // 先声明服务本身
    { provide: SERVICE_ADAPTER, useExisting: ProjectsService }
  ],
  // 其他配置项
})
export class ProjectsModule {}

2. 验证注入令牌的导出与导入路径

确认SERVICE_ADAPTER和ServiceAdapter在库模块中是公开导出的,且使用模块的导入路径完全正确(避免相对路径错误或库包导出配置问题)。

3. 检查指令的注入层级

库中声明的指令默认会从库模块的注入器查找依赖,若使用模块的提供者未覆盖到该层级,可临时给指令注入添加@Optional()装饰器排查:

// 指令构造函数修改
constructor(
  private el: ElementRef, 
  @Inject(SERVICE_ADAPTER) @Optional() protected service: ServiceAdapter
) {}

若添加后不再报错,说明提供者未在指令的有效注入层级内注册。

4. 用useClass替代useExisting验证

如果useExisting配置仍有问题,可先改用useClass测试服务是否能正常注入:

{ provide: SERVICE_ADAPTER, useClass: ProjectsService }

若此配置生效,再排查useExisting的服务令牌匹配问题。


内容的提问来源于stack exchange,提问作者Marco Antonio Gallardo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 06:01:32