<!DOCTYPE html>
<html>
<body>
<ul id="log1"></ul>
<ol id="log2"></ol>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/reflect-metadata/0.1.8/Reflect.min.js"></script>
<script src="script.js"></script>
<script>
var my = new MyClass();
globalSericeLocator.registerService(ILogService, new LogService1());
my.sayHello();
my.sayHello();
my.serviceLocator = new ServiceLocator();
my.serviceLocator.registerService(ILogService, new LogService2());
my.sayHello();
my.sayHello();
</script>
</html>
abstract class ILogService {
abstract log(msg: string): void;
}
class LogService1 implements ILogService {
log(msg: string) {
console.info(msg);
document.getElementById("log1").innerHTML += "<li>" + msg + "</li>";
}
}
class LogService2 implements ILogService {
log(msg: string) {
console.info(msg);
document.getElementById("log2").innerHTML += "<li>" + msg + "</li>";
}
}
class ServiceLocator {
services: [{interfaceType: Function, instance: Object }] = [] as any;
registerService(interfaceType: Function, instance: Object) {
var record = this.services.find(x => x.interfaceType == interfaceType);
if (!record) {
record = { interfaceType: interfaceType, instance: instance};
this.services.push(record);
} else {
record.instance = instance;
}
}
getService(interfaceType: Function) {
return this.services.find(x => x.interfaceType == interfaceType).instance;
}
}
var globalSericeLocator = new ServiceLocator();
function Inject(target: Object, propKey: string): TypedPropertyDescriptor<any> {
var propType = Reflect.getMetadata("design:type", target, propKey);
var descriptor = {
get: function () {
var serviceLocator = this.serviceLocator || globalSericeLocator;
return serviceLocator.getService(propType);
}, configurable: true, enumerable: true
};
Object.defineProperty(target, propKey, descriptor);
return descriptor;
}
class MyClass {
@Inject
private logService: ILogService;
sayHello() {
this.logService.log("Hello there");
}
}
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
}
}