NullInjectorError: нет поставщика услуг в библиотеке

Проблема:

Я работаю в угловом рабочем пространстве и импортирую 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();
  }
}

С вашим образцом кода я могу без проблем использовать CommonService. Можете привести пример на stackblitz?

Matthieu Riegler 13.01.2023 18:15

Находится ли common.module.ts внутри библиотеки (в вашем случае)? Потому что эта ошибка воспроизводится только в том случае, если я импортирую common.module.ts из библиотеки (библиотека создана с использованием cli ng generate library)

Vladyslav Zhadchenko 16.01.2023 09:34

Попробуйте добавить его в providers. Я думаю, что инъекционный токен в обоих случаях разный.

Antoniossss 16.01.2023 11:25

@Antoniossss, токен инъекции тот же (имя класса). Но ваше решение работает. У меня все еще есть вопрос: почему нельзя было внедрить сервис, импортированный из библиотеки? Есть ли в библиотеке какие-то ограничения, которые не позволяют внедрить службу, указанную в providers массиве библиотечного модуля?

Vladyslav Zhadchenko 16.01.2023 12:11

Опять же, я думаю, что токен инъекции отличается (он только выглядит одинаково) - класс, который вы импортируете, не является тем же экземпляром класса, который размещен в провайдерах модуля lib. Это просто хотя и без каких-либо технических знаний, но это объясняет, почему он не работает как A != A', но когда вы используете тот же класс (импортированный таким же образом), тогда это просто A'==A'

Antoniossss 16.01.2023 12:32

@VladyslavZhadchenko я не думаю, что речь идет об ограничениях, а скорее о том, как код скомпилирован как библиотека и что на самом деле import делает

Antoniossss 16.01.2023 12:33

@Antoniossss, если мы импортируем ReactiveFormsModule (это часть сторонней библиотеки), мы все равно можем внедрить службу FormBuilder без необходимости предоставлять ее в массиве app.module.tsproviders. Так что я полагаю, что инъекционный токен не является корнем проблемы.

Vladyslav Zhadchenko 16.01.2023 14:18

Не стесняйтесь искать объяснение (к вашему сведению, FB не является сервисом)

Antoniossss 16.01.2023 15:07

@VladyslavZhadchenko Кажется, я знаю, что не так. Вы не используете public-api для импорта. Ваш импорт должен выглядеть как «импорт X из« lib-name », как для RectiveFormsModule, о котором вы упомянули;)

Antoniossss 17.01.2023 10:45
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
0
9
92
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы используете другой токен инъекции, чем тот, который используется в модуле, поскольку вы импортируете источники напрямую с помощью

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' это наконец-то работает. Спасибо!

Vladyslav Zhadchenko 17.01.2023 15:34

Другие вопросы по теме