I need to dynamically add some components in Angular 14, and I want to be able to control which implementation of an abstract service each component gets, based on some param I have available when I'm creating them.
I'm using ViewContainerRef.createComponent to add them, with a custom Injector that I can set the providers for. This works fine:
makeCustomInjector(param: string) {
return Injector.create({
providers: [
{
provide: AbstractService,
useFactory: (): AbstractService => {
if (param === 'some_value') {
return new AbstractServiceImpA ();
} else {
return new AbstractServiceImpB ();
}
}
}]
});}
const injector: Injector = this.makeCustomInjector('param_value');
const componentRef = this.container.createComponent(DynamicallyAddedComponent, {
injector, environmentInjector
});
But I want to use services which have dependencies, so I add these to the provider for my injector like this:
makeCustomInjector(param: string) {
return Injector.create({
providers: [
{
provide: AbstractService,
useFactory: (serviceC: ServiceC): AbstractService => {
if (param === 'some_value') {
return new AbstractServiceImpA (ServiceC);
} else {
return new AbstractServiceImpB (ServiceC);
}
}, deps: [
ServiceC
]
}]
});}
But I can't get this to work without this error: NullInjectorError: No provider for ServiceC!
What am I doing wrong? Or is there a better way to achieve this?
Got this working by adding a parent injector like this:
makeCustomInjector(param: string) {
return Injector.create({
providers: [
{
provide: AbstractService,
useFactory: (serviceC: ServiceC): AbstractService => {
if (param === 'some_value') {
return new AbstractServiceImpA (ServiceC);
} else {
return new AbstractServiceImpB (ServiceC);
}
}, deps: [
ServiceC
]
}],
parent: this.appRef.injector
});}