Issue
I am authoring an Angular library. It contains a service, which runs initialization logic in the constructor that is required for the library to work properly. I have set up the library module with a static forRoot()
method like the following:
@NgModule({
imports: [CommonModule],
})
export class LibModule {
static forRoot(
config?: Partial<LibConfig>,
): ModuleWithProviders<LibModule> {
return {
ngModule: LibModule,
providers: [{ provide: MY_LIB_CONFIG, useValue: config }],
};
}
// This is necessary, so the service is constructed, even if the service is never injected
constructor(private myLibService: MyLibService) {}
}
Note the constructor where the lib service is injected. Without the constructor, the service initialization logic would only run if the library consumer injects the service, which is not what I want. The service should always be constructed. This works fine for me.
Now I want to offer a more standalone friendly provideMyLib()
function. Here is what I implemented so far:
export function provideMyLib(config?: Partial<LibConfig>): EnvironmentProviders {
return makeEnvironmentProviders([
{ provide: MY_LIB_CONFIG, useValue: config },
]);
}
It works fine in general, but the same problem here, the service is only constructed when the consumer injects it. What I have tried to fix it:
- Adding the service to the providers array -> service is not constructed
- Using the
inject()
function inside theprovideMyLib()
function -> Error:inject
must be run in injection context - Creating a custom injector and inject the service with it -> works, but my service needs to be singleton
- Using variations of
{ provide: MyLibService, ... }
-> service is not constructed
I have also researched implementations of various provide*
functions in the Angular repository, didn't find anything. How can I implement my provide function?
Solution
If you're looking to init something, you need to hook it up to the ENVIRONMENT_INITIALIZER
:
export function provideMyLib(config?: Partial<LibConfig>): EnvironmentProviders {
return makeEnvironmentProviders([
{ provide: MY_LIB_CONFIG, useValue: config }
{
provide: ENVIRONMENT_INITIALIZER,
useValue: () => {
inject(MyLibService)
// do whatever you want here
},
}
}
}
Answered By - Matthieu Riegler
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.