Angular library module inject service with abstract class
I think there should be 'useValue' instead of 'useClass'.
export class ComponentsModule {
static forRoot(pageService): ModuleWithProviders {
return {
ngModule: ComponentsModule,
providers: [
{provide: 'PageService', useClass: pageService}
]
};
}
}
As Sunil Singh said, a normal abstract class is the solution (without @Injectable
).
export abstract class AbstractPageService {
abstract logout(): void;
}
To reuse singleton
Provide in application appModule.ts
{ provide: 'currentCompanyService', useFactory: getCompanyServiceFactory, deps: [AppInitService]}
Create factory which just returns injected instance.
export function getCompanyServiceFactory(appInitService: AppInitService): AppInitService {
return appInitService;
}
Inject in library component
public CustomLibraryComponent {
private companyService: AppInitService;
constructor(@Inject('currentEnvironment') environment: any,
@Inject('currentCompanyService') companyService: AppInitService) {
this.environment = environment;
this.companyService = companyService;
}
}
I used this approach but ran into one problem:
The PageService
is not the same singleton instance in the library as in the application. Because it is provided in multiple modules (application module and the library module), it creates a new instance for each module.
What I ended up doing was providing my service through a string
in the application module:
// app.module.ts in the root application
providers: [
{
provide: 'PageService',
useClass: PageService
}
]
Then injecting the service where needed using @Inject()
// anywhere in the root application where the service is needed
constructor(@Inject('PageService') private pageService: PageService) {}
Then, in the library, I created a simple interface:
export interface AbstractPageService {
logout(): void;
}
Then, I can simply inject the service in the library through the Inject()
decorator and type it using the interface (without the need to implement the interface in the root application):
// anywhere in the library where the service is needed
constructor(@Inject('PageService') private pageService: AbstractPageService) {}
Now both the root application and the library use the same singleton instance of the PageService
, as provided in the root application.