I have two injectable classes in my angular application
@Injectable()
class B {}
@Injectable()
class A {
constructor(b:B) { }
}
I want class A to be Singleton and class B to be Transient
I came to know I can use ReflectiveInjector.resolveAndCreate in class A to get an instance of class B. Any better way of achieving this ?
Since all existing recipes for providers create singletons, even factory, you can create your own injector, inherit all providers from component injector and use resolveAndInstantiate method to get new instances every time:
import { Component, Inject, Injector, ReflectiveInjector } from '@angular/core';
class P {
}
const ps = [];
class C {
constructor(@Inject(P) p) {
ps.push(p);
}
}
@Component({
moduleId: module.id,
selector: 'my-app',
templateUrl: 'app.component.html',
styleUrls: ['app.component.css']
})
export class AppComponent {
name = 'Angular';
constructor(injector: Injector) {
const parent = ReflectiveInjector.resolveAndCreate([P], injector);
const child = parent.resolveAndCreateChild([C]);
const c1 = child.resolveAndInstantiate(C);
const c2 = child.resolveAndInstantiate(C);
console.log(c1 === c2); // false
console.log(ps[0] === ps[1]); // true
}
}
Here is the demo.
Also bear in mind that ReflectiveInjector
is deprecated in @5.x.x. And it seems that there's no alternative in the new StaticInjector. I reported an issue about that.
There is a way to solve this using StaticInjector and functional Javascript. Using Max Koretskyi answer, with few modifications I come up with this:
import { Component, Inject, Injector } from '@angular/core';
class P {
}
const ps = [];
function pFactory() {
return () => new P();
}
@Component({
moduleId: module.id,
providers: [{provide: pFactory, deps: [], useFactory: (pFactory)}],
selector: 'my-app',
templateUrl: 'app.component.html',
styleUrls: ['app.component.css']
})
export class AppComponent {
name = 'Angular';
constructor(@Inject(pFactory) pf) {
let fn = pf.get(pFactory)
ps.push(fn());
ps.push(fn());
console.log(ps[0] === ps[1]); // false
}
}
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