1 Star 2 Fork 0

HappyXiaox / ts.di

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
Readme.md 2.76 KB
一键复制 编辑 原始数据 按行查看 历史
HappyXiaox 提交于 2017-01-17 11:22 . 添加@Inject的用法说明

Dependency Injection for TypeScript

tags: TS DI TypeScript Dependency-Injection


在学习Angular2的时候遇到了依赖注入,发现这个东西非常有用。于是便尝试自己实现了一下。

##API 目前只有几个API:

  • @Injectable()
  • @Singleton()
  • @Inject()
  • @Inject(()=>Type)
  • Injector.get()

##示例

@Injectable()

@Injectable()
class A {
}

@Injectable()
class B {
    private val = '1234';

    constructor(private a: A) {
    }

    getVal() {
        return this.val;
    }

    setVal(newval) {
        this.val = newval;
    }
}

// 使用Injector.get(),不需要提供参数即可获取实例
let b = Injector.get(B);
let b2 = Injector.get(B);

// 测试:同一个Class可以被实例化多次,每个实例都是不同的对象。
let newVal = 'zzzz';
b.setVal(newVal);

assert.equal(b.getVal(), newVal);
assert.equal(b2.getVal(), '1234');

####@Inject() 和@Injectable()的用途一样,只不过这个是用于修饰属性的。

@Injectable()
class A {
    @Inject()
    b: ClassB;
}

####@Singleton

@Singleton()
class SingletonClass {
    private val = '1234';

    constructor(private a: A) {
    }

    get() {
        return this.val;
    }

    set(newval) {
        this.val = newval;
    }
}

let b = Injector.get(SingletonClass);
let b2 = Injector.get(SingletonClass);

// 测试:被@Singleton()装饰的类,所有句柄都应该指向同一个对象
let newVal = 'zzzz';
b.set(newVal);

assert.equal(b.get(), newVal);
assert.equal(b2.get(), newVal);

####@Inject(()=>Type) @Injectable()无法处理A->B->A这样的循环依赖。 当A和B都是单例时,他们相互依赖的情况就很常见。而@Inject(()=>Type)就是为了处理这种依赖而诞生的。 使用@Inject(()=>Type)时,只要依赖循环中存在一个单例,整个循环中的所有实例便都可以被正确创建。

// singleton_class.ts
import {ClassA} from "./class_a"
@Singleton()
class SingletonClass{
}

// class_a.ts
import {SingletonClass} from "./singleton_class"
@Injectable()
class ClassA {
    @Inject(()=>SingletonClass)
    s: SingletonClass;
}

至于为什么要添加一个返回类型的函数作为参数才能解决循环依赖的问题,是因为TypeScript在两个文件相互包含的时候,必定有至少一个类的类型为undefine。添加一个参数其实是不得已为之的解决方案。

构建&测试

>npm install
>npm test

为什么是@Injectable()而不是@Injectable

装饰器本不需要添加一个括号的。就像这样:

@Injectable
class A{}

强制性添加括号是为了和Angular2的装饰器保持一致;也为了实现更好的扩展性。例如@Inject()可以传一个参数进去,解决循环依赖的问题。

TypeScript
1
https://gitee.com/Happyxx/TypescriptDependencyInjection.git
git@gitee.com:Happyxx/TypescriptDependencyInjection.git
Happyxx
TypescriptDependencyInjection
ts.di
master

搜索帮助