首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >面向TypeScript的IOC

面向TypeScript的IOC
EN

Stack Overflow用户
提问于 2012-10-09 16:15:08
回答 7查看 11.2K关注 0票数 10

有了TypeScript,我们现在在JavaScript中有了静态分析和许多面向对象的特性。因此,现在也是时候在客户端逻辑中进行更好的单元测试了,同时我们还需要IOC容器来进行依赖注入,以使代码更易于测试……

那么,有没有人已经体验过这个主题,或者可能知道可以移植到TypeScript的typescript或JavaScript框架的库?

EN

回答 7

Stack Overflow用户

发布于 2015-05-08 06:33:30

我已经开发了一个名为InversifyJS的IoC容器,它具有诸如上下文绑定之类的高级依赖注入特性。

您需要遵循3基本步骤才能使用它:

1.添加注释

注释API基于Angular 2.0:

代码语言:javascript
复制
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(); };

}

2.声明绑定

绑定API基于Ninject:

代码语言:javascript
复制
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>("INinja").to(Ninja);
kernel.bind<IKatana>("IKatana").to(Katana);
kernel.bind<IShuriken>("IShuriken").to(Shuriken);

export default kernel;

3.解析依赖关系

解析API基于Ninject:

代码语言:javascript
复制
import kernel = from "./inversify.config";

var ninja = kernel.get<INinja>("INinja");

expect(ninja.fight()).eql("cut!"); // true
expect(ninja.sneak()).eql("hit!"); // true

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

作为middleware

  • Use identifiers

  • Injection of values

  • Injection of constructors

  • Injection of factories

  • Auto factory

  • Injection of providers的常量依赖项( constant values

  • Injection of constructors

  • Injection of factories

  • Auto factory

  • Injection of providers)的异步标记处理程序(async factory)

  • Activation handlers,用于注入proxies)

  • Multi injections

  • Tagged bindings

  • Custom tag decorators

  • Named bindings

  • Contextual bindings

  • Friendly异常(例如,循环dependencies)

))的

  • 内核模块
  • 标记异常类、字符串文字或符号

您可以在https://github.com/inversify/InversifyJS上了解更多信息

票数 19
EN

Stack Overflow用户

发布于 2015-08-31 08:13:47

我已经为typescript - huject创建了DI库

https://github.com/asvetliakov/huject

示例:

代码语言:javascript
复制
import {Container, FactoryMethod, ConstructorInject, Inject} from 'huject';
class FirstService {
   public constructor(param: number) {}
}
class SecondService {
}

@ConstructorInject
class MyController {
    @Inject
    public service: FirstService;

    public second: SecondService;
    public constructor(service: SecondService) {
        this.second = service;
    }
    ...
}
container.setAllowUnregisteredResolving(true);
container.register(FirstService, [10]); // Register constructor arguments

// FirstService and SecondService will be resolved for container instance
let controller = container.resolve(MyController);

虽然TypeScript接口有一个问题,但我有两个变通方法(使用抽象或简单的类作为接口)

票数 5
EN

Stack Overflow用户

发布于 2015-10-15 16:35:09

或者,您也可以不使用框架,而使用类作为容器,对象工厂作为属性。然后,您可以在测试中继承此类并更改工厂。这种方法是类型安全的,不需要任何装饰器,只需要注册类即可。

代码语言:javascript
复制
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<T>(factory: () => T): () => T  {
    var memo: T = null;
    return function () {
        if(!memo) {
            memo = factory();
        }
        return memo;
    };
}

var singleton = memoize;
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12795666

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档