angular - 如何在 Angular 6+ 中为库级接口的应用程序级具体实现定义可摇树的提供程序?
问题描述
我们目前正在使用 Angular 7。我已经阅读了 Angular 关于依赖注入和创建可摇树提供程序的指南。我已经阅读了十几个关于定义 InjectionTokens 或使用抽象类作为标记来为接口或抽象类提供具体类的问答和博客文章。但他们似乎都假设所有代码都在一个 Angular 项目中。
在我们的架构中,我有一个 Angular 库项目,其中包含我的接口和 InjectionToken:
export const MY_SERVICE = new InjectionToken<MyService>('my-service');
export interface MyService {
someMethod();
}
在那个库项目中,我有一个指令可以注入这个令牌:
export class MyDirective {
constructor(@Inject(MY_SERVICE) myService: MyService) { }
@HostListener('click')
private clicked() {
this.myService.someMethod();
}
}
我想在应用程序级别提供此服务的实际实现,这是另一个导入库项目的 Angular 项目。
Angular 应用程序项目将具有 MyService 的具体实现:
@Injectable({
providedIn: 'root'
})
export class ConcreteMyService implements MyService {
someMethod() {
console.log('Application specific concrete implementation!');
}
}
我之所以使用providedIn: 'root'
,是因为我读过的所有内容都表明这是使该树可摇动所必需的。问题是我不知道如何将它连接到 Angular 的 DI 系统以便在保持可摇树的同时ConcreteMyService
注入。MyDirective
请记住,MyDirective
并且与MyService
处于不同的项目中ConcreteMyService
,并且对此一无所知。这是设计使然,不应更改。
我提到这一点是因为我看到其他人建议在设置 InjectionToken 时执行以下操作:
export const MY_SERVICE = new InjectionToken<MyService>('my-service', {
factory: () => new ConcreteMyService()
});
这里的问题是ConcreteMyService
库项目中不可用,也不应该......这不是一个选项。
我见过的唯一似乎可以完成我所要求的解决方案是将提供程序添加到模块中,例如:
@NgModule({
providers: [
{ provide: MY_SERVICE, useClass: ConcreteMyService }
]
})
export class SomeModule { }
但根据我所阅读的所有内容,这不是可摇树的。
如何使ConcreteMyService
tree-shakable 同时提供给 Angular DI 系统以便在MY_SERVICE
请求我的令牌的情况下使用?请记住库与应用程序项目的分离。
解决方案
推荐阅读
- python - 如何在 django 模型中实现选择字段?
- mysql - 如何根据左连接条件获取mysql值
- python - sklearn.tree.tree 模块在 0.22 版中已弃用,并将在 0.24 版中删除
- python - python - 为什么Python的filecmp在浅模式下报告具有不同修改时间的文件相同?
- php - MySQL 服务器已消失,不一致的错误,由单个脚本引起
- xml - 使 Many2many 字段不可见 (ODOO 12)
- database - 市场上有哪些适用于 Kubernetes/8penshift 的数据库/PostgreSQL 算子?
- handbrake - HandBrake CLI 无法在使用 Flatpack 的 Linux 服务器上运行 - hb_stream_open PATH_TO_FILE 失败
- wxwidgets - wxWidgets TaskBarIcon 作为放置目标
- javascript - 如何显示分页并将卡片限制为 4 项还以角度显示分页