was class -
class A {
constructor(a: number, b: number){
this.c = a + b;
}
}
became class -
@injectable()
class A {
@inject()
public a: number;
@inject()
public b: number;
public c: number;
constructor(){}
init(){
// ???
this.c = a + b;
}
}
Now, how to initialize?
You can use @inject to annotate a constructor:
@injectable()
class A {
public c: number;
constructor(@inject("A") a: number, @inject("B") b: number) {
this.c = a + b;
}
}
each primitive that is to inject, it is better to refuse. And to group related values not only for DI, it is even more terrible. It DI not from the world of js. They will be available only to those who do not understand js. easier to write factory for each dependency than to create interfaces for each VO + constant with a unique type. The first will be faster + all the features es7 (spread operator).
In you example you used property injection. That also works:
@injectable()
class A {
@inject("A")
public a: number;
@inject("B")
public b: number;
public c: number;
// constructor(){} no need for default constructor
init(){
this.c = this.a + this.b;
}
}
If you work with primitive values or classes (not interfaces) @inject annotations are not needed:
@injectable()
class A {
public c: number;
constructor(a: number, b: number) {
this.c = a + b;
}
}
The problem is that a and b are the same type so the same value will be injected unless you declare a constraint:
kernel.bind<number>("Number").toConstantValue(5).when((request: interfaces.Request) => {
return request.target.name.equals("a");
});
kernel.bind<number>("Number").toConstantValue(5).when((request: interfaces.Request) => {
return request.target.name.equals("b");
});
kernel.bind<number>("Number").toConstantValue(5).when((request: interfaces.Request) => {
return request.target.name.equals("a");
});
kernel.bind<number>("Number").toConstantValue(5).when((request: interfaces.Request) => {
return request.target.name.equals("b");
});
vs
const factory = props => new A( ...props );
factory( [ 5, 6 ] );
const factory = ({a, b}) => new A( a, b );
factory( {a: 5, b: 6} );
in js there is a great opportunity to pass parameters when you call, why not use it?
kernel.bind<number>("Number").toConstantValue(5).when((request: interfaces.Request) => {
// I here somehow to access the dependencies?
return request.target.name.equals("a");
});
kernel.bind<number>("Number").toConstantValue(5).when((request: interfaces.Request) => {
// access kernel
let x = request.parentContext.container.get<any>("SOME_ID");
return request.target.name.equals("a");
});