I need to inject a service into an external library for use it in a directive. this directive will be used in diferents apps and in diferents modules in each app. Each module will inject its own service.
Im creating an inyection token and a service interface in the module of the library, and importing its in the modules where are going to be used in the pricipal app.
then I provide the service using useExisting with this token, and in the directive use @Inject(INJECTION_TOKEN) in the constructor.
but i allways have this result when i load the componen where is used directive: "NullInjectorError: R3InjectorError(DashboardModule)[InjectionToken service token -> InjectionToken service token"
In my library module
import { Directive } from './directives/directive.directive';
@NgModule({
exports: [
...,
Directive
],
imports: [CommonModule,...],
declarations: [
...,
Directive
]
})
export class LibraryModule {
}
export const SERVICE_ADAPTER: InjectionToken<ServiceAdapter> =
new InjectionToken('service token');
export interface ServiceAdapter {
a(): void
}
In my library Directive:
import { Directive, ElementRef, EventEmitter, HostListener, Inject, Input, Output } from '@angular/core';
import { ServiceAdapter, SERVICE_ADAPTER } from '../library.module';
@Directive({
selector: '[myDirective]'
})
export class Directive {
@Input() field: string = ''
@Input() method: string = ''
constructor(private el: ElementRef, @Inject(SERVICE_ADAPTER) protected service: ServiceAdapter) {}
@HostListener('keyup', ['$event'])
keyup(event: any) {
...
}
}
In the module where im going tu use it:
...
import { LibraryModule,SERVICE_ADAPTER } from 'Library...';
@NgModule({providers: [
{ provide: SERVICE_ADAPTER, useExisting: ProjectsService }
],
declarations: [
...
],
imports: [
LibraryModule,
]
})
export class ProjectsModule {
}
When I understand you right, the link above is the solution for you. If you want for each lazy loaded module your custom / individual instance of service_adapter "forRoot - Concept" is your solution.
You need a module for your directive in the library like:
export interface IDirectiveModuleConfig {
serviceAdapterConfiguration?: Provider;
}
@NgModule()
export class YourDirectiveModule{
public static forRoot(config: IDirectiveModuleConfig = {}): ModuleWithProviders<YourDirectiveModule> {
return {
ngModule: YourDirectiveModule,
providers: [
config.serviceAdapterConfiguration
]
};
}
}
In your lazy loaded module you can specify how your service will be provided
@NgModule(
{
imports: [
YourDirectiveModule.forRoot({
provide: ServiceAdapter,
useClass: CustomImplementationServiceAdapter
})
]
}
)
export class LazyLoadedModule {
}