var cache = {};
// 通过解析Function.prototype.toString()取得参数名
function getParamNames(func) {
// 正则表达式出自http://krasimirtsonev.com/blog/article/Dependency-injection-in-JavaScript
var paramNames = func.toString().match(/^function\s*[^\(]*\(\s*([^\)]*)\)/m)[1];
paramNames = paramNames.replace(/ /g, '');
paramNames = paramNames.split(',');
return paramNames;
}
var injector = {
// 将func作用域中的this关键字绑定到bind对象上,bind对象可以为空
resolve: function (func, bind) {
// 取得参数名
var paramNames = getParamNames(func);
var params = [];
for (var i = 0; i < paramNames.length; i++) {
// 通过参数名在cache中取出相应的依赖
params.push(cache[paramNames[i]]);
}
// 注入依赖并执行函数
func.apply(bind, params);
}
};
function Notebook() {}
Notebook.prototype.printName = function () {
console.log('this is a notebook');
};
function Pencil() {}
Pencil.prototype.printName = function () {
console.log('this is a pencil');
};
function Student() {}
Student.prototype.write = function (notebook, pencil) {
if (!notebook || !pencil) {
throw new Error('Dependencies not provided!');
}
console.log('writing...');
};
// 提供notebook依赖
cache['notebook'] = new Notebook();
// 提供pencil依赖
cache['pencil'] = new Pencil();
var student = new Student();
injector.resolve(student.write, student); // writing...
function Injector() {
this._cache = {};
}
Injector.prototype.put = function (name, obj) {
this._cache[name] = obj;
};
Injector.prototype.getParamNames = function (func) {
// 正则表达式出自http://krasimirtsonev.com/blog/article/Dependency-injection-in-JavaScript
var paramNames = func.toString().match(/^function\s*[^\(]*\(\s*([^\)]*)\)/m)[1];
paramNames = paramNames.replace(/ /g, '');
paramNames = paramNames.split(',');
return paramNames;
};
Injector.prototype.resolve = function (func, bind) {
var self = this;
var paramNames = self.getParamNames(func);
var params = paramNames.map(function (name) {
return self._cache[name];
});
func.apply(bind, params);
};
var injector = new Injector();
var student = new Student();
injector.put('notebook', new Notebook());
injector.put('pencil', new Pencil())
injector.resolve(student.write, student); // writing...
function Eraser() {}
Eraser.prototype.printName = function () {
console.log('this is an eraser');
};
// 为Student增加draw方法
Student.prototype.draw = function (notebook, pencil, eraser) {
if (!notebook || !pencil || !eraser) {
throw new Error('Dependencies not provided!');
}
console.log('drawing...');
};
injector.put('eraser', new Eraser());
injector.resolve(student.draw, student);
Student.prototype.write.depends = ['notebook', 'pencil'];
Student.prototype.draw.depends = ['notebook', 'pencil', 'eraser'];
Injector.prototype.resolve = function (func, bind) {
var self = this;
// 首先检查func上是否有depends属性,如果没有,再用正则表达式解析
func.depends = func.depends || self.getParamNames(func);
var params = func.depends.map(function (name) {
return self._cache[name];
});
func.apply(bind, params);
};
var student = new Student();
injector.resolve(student.write, student); // writing...
injector.resolve(student.draw, student); // draw...
class Pencil {
public printName() {
console.log('this is a pencil');
}
}
class Eraser {
public printName() {
console.log('this is an eraser');
}
}
class Notebook {
public printName() {
console.log('this is a notebook');
}
}
class Student {
pencil: Pencil;
eraser: Eraser;
notebook: Notebook;
public constructor(notebook: Notebook, pencil: Pencil, eraser: Eraser) {
this.notebook = notebook;
this.pencil = pencil;
this.eraser = eraser;
}
public write() {
if (!this.notebook || !this.pencil) {
throw new Error('Dependencies not provided!');
}
console.log('writing...');
}
public draw() {
if (!this.notebook || !this.pencil || !this.eraser) {
throw new Error('Dependencies not provided!');
}
console.log('drawing...');
}
}
var dependenciesMap = {};
var injector = {
resolve: function (constructor) {
var dependencies = dependenciesMap[constructor.name];
dependencies = dependencies.map(function (dependency) {
return new dependency();
});
// 如果可以使用ES6的语法,下面的代码可以合并为一行:
// return new constructor(...dependencies);
var mockConstructor: any = function () {
constructor.apply(this, dependencies);
};
mockConstructor.prototype = constructor.prototype;
return new mockConstructor();
}
};
function Inject(...dependencies) {
return function (constructor) {
dependenciesMap[constructor.name] = dependencies;
return constructor;
};
}
// 装饰器的使用非常简单,只需要在类定义的上方添加一行代码
// Inject是装饰器的名字,后面是function Inject的参数
@Inject(Notebook, Pencil, Eraser)
class Student {
pencil: Pencil;
eraser: Eraser;
notebook: Notebook;
public constructor(notebook: Notebook, pencil: Pencil, eraser: Eraser) {
this.notebook = notebook;
this.pencil = pencil;
this.eraser = eraser;
}
public write() {
if (!this.notebook || !this.pencil) {
throw new Error('Dependencies not provided!');
}
console.log('writing...');
}
public draw() {
if (!this.notebook || !this.pencil || !this.eraser) {
throw new Error('Dependencies not provided!');
}
console.log('drawing...');
}
}
var student = injector.resolve(Student);
console.log(student instanceof Student); // true
student.notebook.printName(); // this is a notebook
student.pencil.printName(); // this is a pencil
student.eraser.printName(); // this is an eraser
student.draw(); // drawing
student.write(); // writing
function RadicalInject(...dependencies){
var wrappedFunc:any = function (target: any) {
dependencies = dependencies.map(function (dependency) {
return new dependency();
});
// 使用mockConstructor的原因和上例相同
function mockConstructor() {
target.apply(this, dependencies);
}
mockConstructor.prototype = target.prototype;
// 为什么需要使用reservedConstructor呢?因为使用RadicalInject对Student方法装饰之后,
// Student指向的构造函数已经不是一开始我们声明的class Student了,而是这里的返回值,
// 即reservedConstructor。Student的指向变了并不是一件不能接受的事,但是如果要
// 保证student instanceof Student如我们所期望的那样工作,这里就应该将
// reservedConstructor的prototype属性指向原Student的prototype
function reservedConstructor() {
return new mockConstructor();
}
reservedConstructor.prototype = target.prototype;
return reservedConstructor;
}
return wrappedFunc;
}
@RadicalInject(Notebook, Pencil, Eraser)
class Student {
pencil: Pencil;
eraser: Eraser;
notebook: Notebook;
public constructor() {}
public constructor(notebook: Notebook, pencil: Pencil, eraser: Eraser) {
this.notebook = notebook;
this.pencil = pencil;
this.eraser = eraser;
}
public write() {
if (!this.notebook || !this.pencil) {
throw new Error('Dependencies not provided!');
}
console.log('writing...');
}
public draw() {
if (!this.notebook || !this.pencil || !this.eraser) {
throw new Error('Dependencies not provided!');
}
console.log('drawing...');
}
}
// 不再出现injector,直接调用构造函数
var student = new Student();
console.log(student instanceof Student); // true
student.notebook.printName(); // this is a notebook
student.pencil.printName(); // this is a pencil
student.eraser.printName(); // this is an eraser
student.draw(); // drawing
student.write(); // writing
interface NotebookInterface {
printName(): void;
}
interface PencilInterface {
printName(): void;
}
interface EraserInterface {
printName(): void;
}
interface StudentInterface {
notebook: NotebookInterface;
pencil: PencilInterface;
eraser: EraserInterface;
write(): void;
draw(): void;
}
class Notebook implements NotebookInterface {
public printName() {
console.log('this is a notebook');
}
}
class Pencil implements PencilInterface {
public printName() {
console.log('this is a pencil');
}
}
class Eraser implements EraserInterface {
public printName() {
console.log('this is an eraser');
}
}
class Student implements StudentInterface {
notebook: NotebookInterface;
pencil: PencilInterface;
eraser: EraserInterface;
constructor(notebook: NotebookInterface, pencil: PencilInterface, eraser: EraserInterface) {
this.notebook = notebook;
this.pencil = pencil;
this.eraser = eraser;
}
write() {
console.log('writing...');
}
draw() {
console.log('drawing...');
}
}
import { Inject } from "inversify";
@Inject("NotebookInterface", "PencilInterface", "EraserInterface")
class Student implements StudentInterface {
notebook: NotebookInterface;
pencil: PencilInterface;
eraser: EraserInterface;
constructor(notebook: NotebookInterface, pencil: PencilInterface, eraser: EraserInterface) {
this.notebook = notebook;
this.pencil = pencil;
this.eraser = eraser;
}
write() {
console.log('writing...');
}
draw() {
console.log('drawing...');
}
}
import { TypeBinding, Kernel } from "inversify";
var kernel = new Kernel();
kernel.bind(new TypeBinding("NotebookInterface", Notebook));
kernel.bind(new TypeBinding("PencilInterface", Pencil));
kernel.bind(new TypeBinding("EraserInterface", Eraser));
kernel.bind(new TypeBinding("StudentInterface", Student));
var student: StudentInterface = kernel.resolve("StudentInterface");
console.log(student instanceof Student); // true
student.notebook.printName(); // this is a notebook
student.pencil.printName(); // this is a pencil
student.eraser.printName(); // this is an eraser
student.draw(); // drawing
student.write(); // writing
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有