Skip to content

Instantly share code, notes, and snippets.

@adatta02
Created November 27, 2017 01:46
Show Gist options
  • Select an option

  • Save adatta02/2fac8cb534679769b80038c0d0432c33 to your computer and use it in GitHub Desktop.

Select an option

Save adatta02/2fac8cb534679769b80038c0d0432c33 to your computer and use it in GitHub Desktop.
An example TypeScript DI system
import "reflect-metadata";
type Newable<T> = new (...args : any[]) => T;
class Injector {
private static constructedInstances : {cx: Newable<any>, object: any}[] = [];
public static inject<T>(originalConstructor : Newable<T>) : Newable<T> {
const paramTypes = Reflect.getOwnMetadata("design:paramtypes", originalConstructor);
if(paramTypes.length == 0){
Injector.constructedInstances.push({cx: originalConstructor, object: null});
return originalConstructor;
}
const newArgs = paramTypes.map((f : any) => Injector.get(f));
const newConstructor = originalConstructor.bind(null, newArgs);
Injector.constructedInstances.push({cx: newConstructor, object: null});
return newConstructor;
}
public static get(cx : Newable<any>) : any {
const ci = this.constructedInstances.find(f => f.cx == cx);
if(!ci){
throw "Invalid DI configuration.";
}
if(ci.object == null){
ci.object = new ci.cx();
}
return ci.object;
}
}
function Inject<T>(originalConstructor : Newable<T>) : Newable<T> {
return Injector.inject(originalConstructor);
}
@Inject
class Engine {
displacement : number;
maker : string;
constructor(){
this.maker = "Tesla";
this.displacement = 500;
}
}
@Inject
class Car {
constructor(private ex : Engine){}
}
console.log( Injector.get(Car) );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment