Я работаю в угловом рабочем пространстве и импортирую common.module.ts
из библиотеки (библиотека, созданная с помощью ng generate library
) в свой app.module.ts
, но когда я ввожу CommonService
в app.component.ts
, я получаю сообщение об ошибке:
main.ts:11 ERROR NullInjectorError: R3InjectorError(AppModule)[CommonService -> CommonService -> CommonService]:
NullInjectorError: No provider for CommonService!
В CommonService
есть провайдер для common.module.ts
, поэтому я ожидаю, что при внедрении службы в компонент не должно возникать ошибок.
common.module.ts
import { NgModule } from '@angular/core';
import { CommonComponent } from './common.component';
import { HttpClientModule } from '@angular/common/http';
import { CommonService } from './common.service';
@NgModule({
declarations: [],
imports: [],
exports: [],
providers: [
CommonService
]
})
export class CommonModule {
}
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';
import { CommonModule } from 'common';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule,
CommonModule
],
providers: [
],
bootstrap: [AppComponent]
})
export class AppModule {
}
app.component.ts
import { Component } from '@angular/core';
import { CommonService } from '../../../common/src/lib/common.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.less']
})
export class AppComponent {
constructor(private common2: CommonService) {
}
}
common.service.ts
@Injectable()
export class CommonService {
constructor() {
this.initProps();
}
}
Находится ли common.module.ts
внутри библиотеки (в вашем случае)? Потому что эта ошибка воспроизводится только в том случае, если я импортирую common.module.ts
из библиотеки (библиотека создана с использованием cli ng generate library
)
Попробуйте добавить его в providers
. Я думаю, что инъекционный токен в обоих случаях разный.
@Antoniossss, токен инъекции тот же (имя класса). Но ваше решение работает. У меня все еще есть вопрос: почему нельзя было внедрить сервис, импортированный из библиотеки? Есть ли в библиотеке какие-то ограничения, которые не позволяют внедрить службу, указанную в providers
массиве библиотечного модуля?
Опять же, я думаю, что токен инъекции отличается (он только выглядит одинаково) - класс, который вы импортируете, не является тем же экземпляром класса, который размещен в провайдерах модуля lib. Это просто хотя и без каких-либо технических знаний, но это объясняет, почему он не работает как A != A'
, но когда вы используете тот же класс (импортированный таким же образом), тогда это просто A'==A'
@VladyslavZhadchenko я не думаю, что речь идет об ограничениях, а скорее о том, как код скомпилирован как библиотека и что на самом деле import
делает
@Antoniossss, если мы импортируем ReactiveFormsModule
(это часть сторонней библиотеки), мы все равно можем внедрить службу FormBuilder
без необходимости предоставлять ее в массиве app.module.ts
providers
. Так что я полагаю, что инъекционный токен не является корнем проблемы.
Не стесняйтесь искать объяснение (к вашему сведению, FB не является сервисом)
@VladyslavZhadchenko Кажется, я знаю, что не так. Вы не используете public-api для импорта. Ваш импорт должен выглядеть как «импорт X из« lib-name », как для RectiveFormsModule, о котором вы упомянули;)
Вы используете другой токен инъекции, чем тот, который используется в модуле, поскольку вы импортируете источники напрямую с помощью
import { CommonService } from '../../../common/src/lib/common.service';
выставьте его через публичный API в вашей библиотеке, затем используйте его через публичный API так же, как вы делаете с модулем
import { CommonModule } from 'common';
например
import { CommonService } from 'common';
и тогда это сработает.
Прямо сейчас вы ожидаете, что скомпилированный объект в библиотеке будет равен объекту, который скомпилирован непосредственно в ваше приложение, что не будет работать (класс в модуле — это не тот класс, который вы импортируете (компилируете его снова))
После ng build library
и использования import { CommonModule } from 'common'
это наконец-то работает. Спасибо!
С вашим образцом кода я могу без проблем использовать CommonService. Можете привести пример на stackblitz?