IOC for TypeScript TypeScript的IOC(Inversion of Control,控制反转)

10 浏览
0 Comments

IOC for TypeScript TypeScript的IOC(Inversion of Control,控制反转)

有了TypeScript,我们现在可以在JavaScript中进行静态分析并使用许多面向对象的特性。

所以现在是时候在客户端逻辑中进行更好的单元测试了,同时我们还需要IOC容器来进行依赖注入,以使代码更易于测试...

所以,有人已经在这个主题上有过经验吗?或者知道可以移植到TypeScript的JavaScript框架的库吗?

0
0 Comments

IOC (Inversion of Control) 是一种设计模式,它将对象的创建和依赖注入的过程从代码中解耦出来,使得代码更加灵活和可维护。在 TypeScript 中,使用 IOC 可以更好地管理对象之间的依赖关系,并且提供一种类型安全的方式进行对象的创建和注入。

在上述代码中,提到了一种不使用框架的方式实现 IOC,即使用类作为容器,将对象工厂作为属性。通过继承这个类,在测试中可以修改工厂,实现对象的替换。这种方式不需要使用任何装饰器,只需要注册类即可。

具体实现如下:

class B {
    echo() {
        alert('test');
    }   
}
class A {
    constructor(private b: B) {
        b.echo();
    }
}
class Container {
    A = () => new A(this.B());
    B = singleton(() => new B()); 
}
var c = new Container();
var a = c.A();
// singleton helper:
function memoize(factory: () => T): () => T  {
    var memo: T = null;
    return function () {
        if(!memo) {
            memo = factory();
        }
        return memo;
    };
}
var singleton = memoize;

在这段代码中,我们定义了两个类 A 和 B。类 A 的构造函数依赖于类 B 的实例。为了实现依赖注入,我们使用了一个名为 Container 的类作为容器,通过注册类的方式来实现对象的创建和注入。Container 中定义了两个属性 A 和 B,分别是类 A 和类 B 的工厂函数。通过调用 Container 的 A 属性,可以实例化一个 A 类的对象,并且自动注入一个 B 类的实例。

为了实现对象的单例模式,我们使用了一个名为 memoize 的辅助函数,它接受一个工厂函数作为参数,并返回一个新的函数。这个新的函数首先判断 memo 变量是否为空,如果为空则调用工厂函数创建对象并赋值给 memo,然后返回 memo。这样就实现了对象的单例模式。

通过使用类作为容器并实现对象的工厂函数,我们可以更灵活地管理对象的依赖关系,并且提供一种类型安全的方式创建和注入对象。这种方式不需要使用任何框架,只需要注册类即可实现 IOC 的效果。

0
0 Comments

随着TypeScript的流行,越来越多的开发者开始关注如何在TypeScript中实现依赖注入(Dependency Injection,简称DI)。然而,当前市场上尚未出现一个完全适用于TypeScript的依赖注入系统,这也是问题的根源。为了解决这个问题,开发者asvetliakov创建了一个名为huject的DI库。

在上述示例中,我们可以看到如何使用huject进行依赖注入。首先,我们需要导入库中提供的一些装饰器和类,如Container、FactoryMethod、ConstructorInject和Inject。然后,我们可以创建需要进行依赖注入的类,比如FirstService、SecondService和MyController。在MyController中,我们可以看到它依赖于SecondService,并通过构造函数进行注入。最后,我们可以使用container.resolve方法获取到已经注入了依赖的MyController实例。

然而,目前huject在处理TypeScript接口时存在一些问题。为了解决这个问题,asvetliakov提供了两种解决方案:使用抽象类或者简单类作为接口。这些解决方案可以让开发者在TypeScript中更加灵活地使用依赖注入。

huject为TypeScript开发者提供了一个可靠的依赖注入解决方案。开发者可以通过该库实现代码的解耦和可测试性的提升。感谢asvetliakov的辛勤努力,为TypeScript社区贡献了一个优秀的开源项目。

0
0 Comments

IoC for TypeScript(InversifyJS)的出现原因是为了实现高级依赖注入功能,包括上下文绑定。下面是使用它的基本步骤以及解决方法。

第一步:添加注解

注解API基于Angular 2.0:

import { injectable, inject } from "inversify";
@injectable()
class Katana implements IKatana {
    public hit() {
        return "cut!";
    }
}
@injectable()
class Shuriken implements IShuriken {
    public throw() {
        return "hit!";
    }
}
@injectable()
class Ninja implements INinja {
    private _katana: IKatana;
    private _shuriken: IShuriken;
    public constructor(
        @inject("IKatana") katana: IKatana,
        @inject("IShuriken") shuriken: IShuriken
    ) {
        this._katana = katana;
        this._shuriken = shuriken;
    }
    public fight() { return this._katana.hit(); };
    public sneak() { return this._shuriken.throw(); };
}

第二步:声明绑定

绑定API基于Ninject:

import { Kernel } from "inversify";
import { Ninja } from "./entities/ninja";
import { Katana } from "./entities/katana";
import { Shuriken} from "./entities/shuriken";
var kernel = new Kernel();
kernel.bind("INinja").to(Ninja);
kernel.bind("IKatana").to(Katana);
kernel.bind("IShuriken").to(Shuriken);
export default kernel;

第三步:解决依赖关系

解决依赖关系的API基于Ninject:

import kernel = from "./inversify.config";
var ninja = kernel.get("INinja");
expect(ninja.fight()).eql("cut!"); // true
expect(ninja.sneak()).eql("hit!"); // true

最新版本(2.0.0)支持许多用例,包括:

- Kernel模块

- Kernel中间件

- 使用类、字符串字面量或Symbols作为依赖标识符

- 注入常量值

- 注入类构造函数

- 注入工厂

- 自动工厂

- 注入提供者(异步工厂)

- 激活处理程序(用于注入代理)

- 多重注入

- 带标签的绑定

- 自定义标签装饰器

- 命名绑定

- 上下文绑定

- 友好异常(例如循环依赖)

更多信息请参考https://github.com/inversify/InversifyJS

是否总是需要第二步的绑定?

绑定是必需的,但有一个实用工具可以为您声明绑定:github.com/inversify/inversify-binding-decorators

是否可以在没有TypeScript的情况下使用?

是的!请查看github.com/inversify/InversifyJS/blob/master/wiki/…github.com/inversify/inversify-vanillajs-helpers

IoC for TypeScript(InversifyJS)的出现是为了实现高级依赖注入功能,并提供了一套简单易用的API来实现注解、声明绑定和解决依赖关系。它支持许多用例,并且可以在TypeScript和JavaScript中使用。

0