Обновленный ответ
Если вы хотите использовать разные реализации для одной и той же службы, вы должны создать InjectionToken и предоставить правильную реализацию для вашего интерфейса в объявлениях вашего модуля.
Интерфейс - lang.service.ts
Создать токен впрыска, который будет распознаваться инжектором, набранным с ILangService
interface
export const LangService = new InjectionToken<ILangService>('LangService');
export interface ILangService { }
1-й модуль - english.module.ts
Укажите EnglishLangService
для токена инъекции LangService
, где EnglishLangService
реализует ILangService
интерфейс
import { LangService } from './services/lang.service';
import { EnglishLangService } from './services/english-lang.service';
@NgModule({
declarations: [ LandingComponent ],
providers: [
{ provide: LangService, useClass: EnglishLangService }
]
})
export class EnglishModule { }
2-й модуль - french.module.ts
Укажите FrenchLangService
для токена инъекции LangService
, где FrenchLangService
реализует ILangService
интерфейс
import { LangService } from './services/lang.service';
import { FrenchLangService } from './services/french-lang.service';
@NgModule({
declarations: [ LandingComponent ],
providers: [
{ provide: LangService, useClass: FrenchLangService }
]
})
export class FrenchModule { }
Компонент - landing.component.ts
Таким образом, вы можете вставить LangService
в ваш компонент, и инжектор получит реализацию, предоставленную в вашем модуле
import { LangService } from '../../services/lang.service';
@Component({
selector: 'app-landing',
templateUrl: './landing.component.html',
styleUrls: ['./landing.component.less']
})
export class LandingComponent {
constructor(
private http: HttpClient,
private langService: LangService,
) { }
}
Тестирование - mock-lang.service.ts
При тестировании вы сможете предоставить макетную реализацию таким же образом, как вы предоставляете правильную реализацию в своих прикладных модулях
import { LangService } from './services/lang.service';
import { MockLangService } from './services/mock-lang.service';
TestBed.configureTestingModule({
providers: [
{ provide: LangService, useClass: MockLangService },
],
});
Оригинальный ответ
Вы должны импортировать свой сервис с классом вместо интерфейса
import { LangService } from '../../services/lang.service';
@Component({
selector: 'app-landing',
templateUrl: './landing.component.html',
styleUrls: ['./landing.component.less']
})
export class LandingComponent {
constructor(
private http: HttpClient,
private langService: LangService;
) { }
}
Также не забудьте установить декоратор @Injectable()
в объявлении класса обслуживания
import { Injectable } from '@angular/core';
@Injectable()
export class LangService implements ILangService { }
И, конечно, вы должны предоставить услугу вашему модулю
import { LangService } from './services/Lang.service';
@NgModule({
declarations: [
AppComponent,
LandingComponent,
],
imports: [ ... ],
providers: [
LangService
],
bootstrap: [AppComponent]
})
export class AppModule { }
Вы можете прочитать о внедрении угловой зависимости здесь: https://angular.io/guide/dependency-injection
Еще одна интересная ссылка для предварительных объявлений об услугах: https://offering.solutions/blog/articles/2018/08/17/using-useclass-usefactory-usevalue-useexisting-with-treeshakable-providers-in-angular/