I have an Angular2 DI question. Say I have a TestService
and I want to use 2 different instances of this service inside the same component. If I simply add a provider to the component and I add the 2 instances to the constructor I end up with the same service instance. For example:
TestService
import {Injectable} from "@angular/core";
@Injectable()
export class TestService {
public id: number = Math.random();
public toString(): string {
return "Id: " + this.id;
}
}
Test component
import {Component, Input, OnInit} from "@angular/core";
import {TestService} from "../../services/test.service";
@Component({
providers: [TestService]
})
export class TestComponent implements OnInit {
constructor(private _testService1: TestService, private _testService2: TestService) { };
ngOnInit() {
console.log("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", this._testService1.toString());
console.log("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", this._testService2.toString());
}
}
Result in console
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Id: 0.24242492129168425
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB Id: 0.24242492129168425
Can someone pls tell me if there's a way to use Angular2's DI mechanism to inject multiple different instances of a service within the same component or should I just drop the DI for this particular case and create my instances manually with a manual constructor?
Thanks in advance
Now it is a service that can be used between parent and child components. In this case, service is a non-singleton nature. It will create multiple instances of a service. Every time a new instance of provided service will be created when a component is used inside another component.
@Injectable() lets Angular know that a class can be used with the dependency injector. @Injectable() is not strictly required if the class has other Angular decorators on it or does not have any dependencies.
Dependency injection (DI) is a paradigm. The way it works in Angular is through a hierarchy of injectors. A class receives its resources without having to create or know about them. Injectors receive instruction and instantiate a service depending on which one was requested.
In this article we'll explore when and why Angular creates two instances of the same service and what solutions exist to ensure a service remains a singleton in the entire application.
Angular DI maintains a single instance per provider. In your case if you have two constructor parameters with the same type, they resolve to the same instance. What you can do is to provide a factory function (different from a simple useFactory provider event though it uses it as well) If you have a fixed number of instances this should work:
Angular DI maintains a single instance per provider. In your case if you have two constructor parameters with the same type, they resolve to the same instance.
Angular will create new instances for any of InjectionToken or Injectable in cases of using: This is happening because Angular creates a new module Injector for any lazy loaded module, this behavior is perfectly described in docs and this article.
Any consumers of those classes also do not need to know anything. DI saves classes and consumers alike from having to know more than necessary. Yet the code is as modular as it was before thanks to the mechanisms supporting DI in Angular. Services are a key benefactor of DI.
You can inject a factory that returns a new instance every time you call it:
@NgModule({
providers: [{
provide: 'testService',
useFactory: (/* TestService deps here like `http`*/) =>
(/* params */) => new TestService(/* http */),
deps: [/* TestService deps here like `Http`*/ ]
}]
})
@Component(...)
export class TestComponent implements OnInit {
constructor(@Inject('testService') private _testServiceFactory) { };
ngOnInit() {
console.log("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", this._testServiceFactory( /* params */).toString());
console.log("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", this._testServiceFactory().toString());
}
}
Plunker example (check the output in the browser console when you click the button)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With