Suppose I have an Angular 2 component-directive, where I want the injected dependency that the component uses to be determined by an @Input().
I want to write someth
In general, same approach is described in Angular2 documentation: InjectorComponent
@Component({
providers: [Car, Engine, Tires, heroServiceProvider, Logger]
})
export class InjectorComponent {
car: Car = this.injector.get(Car);
heroService: HeroService = this.injector.get(HeroService);
hero: Hero = this.heroService.getHeroes()[0];
constructor(private injector: Injector) { }
}
You must inject Injector
in constructor and list all services in providers
property of @Component
annotation. Then you can injector.get(type)
, where type
will be resolved from your @Input
. As per documentation, Service
is not actually injected until you ask for it (.get()
).
There is a service named Inject in @angular/core module. With @Inject you can achieve alternative way of injection. But that can be done only in constructor.
So you will need to put component's inputs in the inputs array of your @component decorator (do not use @Input decorator inside class) and then inject that input variable in constructor.
I would like to take Estus Flask answer a step further and create a logic that imports the service rather than having to declare the names as array objects.
Basically, we just have to pass in the path
and name
of the service and the rest is almost the same.
public _dynamicService: any;
dynamicDI(service_path, service_name){
import(service_path).then(s => {
this._dynamicService = this.injector.get<any>(s['service_name']);
})
}
Now, you can access the functions inside the dynamicService
as follows:
(Let's assume we have a http observable fn in the service we need)
this._dynamicService['your_function_name']().subscribe(res=> { console.log(res) } );
It is
// can be a service also for overriding and testing
export const trendyServiceMap = {
serviceA: ServiceA,
serviceB: ServiceB
}
constructor(private injector: Injector) {}
...
ngOnInit() {
if (trendyServiceMap.hasOwnProperty(this.use)) {
this.service = this.injector.get<any>(trendyServiceMap[this.use]);
} else {
throw new Error(`There's no such thing as '${this.use}'`);
}
}