我想在Angular中使用Interface指定DI,所以我问了ChatGPT
在Angular+SpringBoot的Web应用程序中,经常会使用到DI容器。但是实际上,两者都有不同的DI方式:
– Angular -> 指定实际类进行DI
– SpringBoot -> 指定接口进行DI
在常规实现中,依赖注入(DI)意味着使用方只需关注接口,而将实现类的解决交给DI容器。因此,我曾经认为在Angular中是否也可以指定接口进行DI。
或许在Angular领域这是常识,但我之前不知道,所以问了问ChatGPT。(我有点跟不上潮流…)
与ChatGPT的对话

这家伙是个天才吗!?
太厉害了吧。。。我在2、3分钟内就了解了我想知道的事情。。。
不过,由于ChatGPT有可能说谎,我会亲自试一试。
执行
界面
export interface ServiceInterface {
show: () => void;
}
实现类(prod)
import { Injectable } from '@angular/core';
import { ServiceInterface } from './service.interface';
@Injectable({
providedIn: 'root',
})
export class ProdService implements ServiceInterface {
constructor() {}
show() {
console.log('This is ProdService.');
}
}
实现类(test)
import { Injectable } from '@angular/core';
import { ServiceInterface } from './service.interface';
@Injectable({
providedIn: 'root',
})
export class TestService implements ServiceInterface {
constructor() {}
show() {
console.log('This is TestService.');
}
}
好的,只需在app.module.ts文件的providers部分设置工厂,然后在使用类中进行依赖注入就可以了。
假设在prod环境中运行时,会注入prod.service.ts,而在其他情况下会注入test.service.ts并运行。

提供无法指定给interface呢…难道是被ChatGPT骗了吗…
根据我的调查,似乎有两种方法可行:
1. 实现继承自Interface的抽象类并将抽象类指定为provide。
2. 生成与Interface相关的InjectionToken,并将其指定为provide。
我个人的喜好是使用方法二来处理。
import { environment } from 'src/environments/environment';
import { ProdService } from './service/prod.service';
import { TestService } from './service/test.service';
import { ServiceInterface } from './service/service.interface';
// environmentでインスタンス化するクラスを変えていく
const myFactory = () => {
return environment.production ? new ProdService() : new TestService();
};
// ServiceInterfaceに紐づくInjectionTokenを生成する
export const SERVICE_TOKEN = new InjectionToken<ServiceInterface>(
'service.interface'
);
@NgModule({
declarations: [AppComponent, CustomTooltipComponent, CustomTooltipDirective],
imports: [BrowserModule, AppRoutingModule, OverlayModule],
providers: [
{
// 生成したInjectionTokenをprovideに指定する
provide: SERVICE_TOKEN,
useFactory: myFactory,
},
],
bootstrap: [AppComponent],
})
export class AppModule {}
只需编写使用类即可。
import { Component, Inject } from '@angular/core';
import { SERVICE_TOKEN } from './app.module';
import { ServiceInterface } from './service/service.interface';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
title = 'angular-sample';
// DIする際に@InjectでInjectionTokenを指定する
constructor(@Inject(SERVICE_TOKEN) sv: ServiceInterface) {
sv.show();
}
}
个人觉得用@Inject来指定InjectionToken有点微妙…
能否有其他办法呢?如果是的话,用抽象类方式来实现可能是更好的选择。
现在,确认启动
ng serve --configutaion production

ng serve

哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇,太厉害了!!经历了一番波折,但最终实现了我想做的事情。ChatGPT太棒了!!!
我试用过后,不是像被AI夺走工作或者自认毫无价值那样消极的感觉,而是开始对使用ChatGPT不断提升自己感到兴奋。
总之,它的信息收集效率真是非常高,甚至可以用来征求案例A和案例B哪个更好的建议。在ChatGPT的回答中,我学到了很多有益的东西。
只是,像这次一样存在着虚假信息,所以更需要深入思考,通过搜索来获取证实才是重要的。另外,由于咨询类问题也可以进行引导性讯问,ChatGPT有时会提供顾虑的答案,所以询问A和B方案的优缺点,或者提出关注公平性的问题会更好吧。
这就是上面的内容。