typescript 打字稿的国际奥委会
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12795666/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
IOC for TypeScript
提问by Denis Agarev
With TypeScript now we have static analyze and many OOP features in JavaScript. So it's also time to have better unit tests in client side logic and as well we need IOC container for dependency injections to make code more testable...
现在有了 TypeScript,我们在 JavaScript 中有了静态分析和许多 OOP 特性。因此,现在也是在客户端逻辑中进行更好的单元测试的时候了,而且我们需要 IOC 容器进行依赖注入以使代码更易于测试......
So, have someone already experienced it this subject or maybe know libraries for typescript or JavaScript frameworks that can be porting to TypeScript?
那么,是否有人已经体验过这个主题,或者可能知道可以移植到 TypeScript 的 typescript 或 JavaScript 框架的库?
回答by Remo H. Jansen
I have developed an IoC container called InversifyJS with advanced dependency injection features like contextual bindings.
我开发了一个名为 InversifyJS 的 IoC 容器,具有高级依赖注入功能,如上下文绑定。
You need to follow 3 basic stepsto use it:
您需要遵循3 个基本步骤来使用它:
1. Add annotations
1. 添加注释
The annotation API is based on Angular 2.0:
注解 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(); };
}
2. Declare bindings
2. 声明绑定
The binding API is based on Ninject:
绑定 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>("INinja").to(Ninja);
kernel.bind<IKatana>("IKatana").to(Katana);
kernel.bind<IShuriken>("IShuriken").to(Shuriken);
export default kernel;
3. Resolve dependencies
3. 解决依赖
The resolution API is based on Ninject:
解析API基于Ninject:
import kernel = from "./inversify.config";
var ninja = kernel.get<INinja>("INinja");
expect(ninja.fight()).eql("cut!"); // true
expect(ninja.sneak()).eql("hit!"); // true
The latest release (2.0.0) supports many use cases:
最新版本 (2.0.0) 支持许多用例:
- Kernel modules
- Kernel middleware
- Use classes, string literals or Symbols as dependency identifiers
- Injection of constant values
- Injection of class constructors
- Injection of factories
- Auto factory
- Injection of providers (async factory)
- Activation handlers (used to inject proxies)
- Multi injections
- Tagged bindings
- Custom tag decorators
- Named bindings
- Contextual bindings
- Friendly exceptions (e.g. Circular dependencies)
- 内核模块
- 内核中间件
- 使用类、字符串文字或符号作为依赖标识符
- 注入常数值
- 类构造函数的注入
- 工厂注塑
- 汽车厂
- 提供程序的注入(异步工厂)
- 激活处理程序(用于注入代理)
- 多次注射
- 标记绑定
- 自定义标签装饰器
- 命名绑定
- 上下文绑定
- 友好异常(例如循环依赖)
You can learn more about it at https://github.com/inversify/InversifyJS
回答by Alexey Svetliakov
I have created DI library for typescript - huject
我为打字稿创建了 DI 库 - huject
https://github.com/asvetliakov/huject
https://github.com/asvetliakov/huject
Example:
例子:
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);
There is a problem with TypeScript interfaces though, but i have 2 workarounds (use abstract or simple class as interface)
虽然 TypeScript 接口存在问题,但我有 2 个解决方法(使用抽象类或简单类作为接口)
回答by jka
Alternatively you can just use no framework and use class as container with object factories as properties. You can then inherit this class in tests and change factories. This approach is type safe and do not require any decorators, just registration of classes.
或者,您可以不使用框架并使用类作为容器,对象工厂作为属性。然后,您可以在测试和更改工厂中继承此类。这种方法是类型安全的,不需要任何装饰器,只需注册类。
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;
回答by Fenton
For now, you can use dependency injection in JavaScript without the IOC part. It is up to you whether you write a "manual" resolver, or factories, or whatever DI pattern you prefer.
目前,您可以在没有 IOC 部分的情况下在 JavaScript 中使用依赖注入。是否编写“手动”解析器、工厂或任何您喜欢的 DI 模式取决于您。
When the ECMAScript 6 standard is adopted, it may make the concept of IOC possible in JavaScript.
当采用 ECMAScript 6 标准时,可能会使 JavaScript 中的 IOC 概念成为可能。
回答by Monroe Thomas
We've been using a simple dependency injection container which uses AMD define/require - like syntax. The original implementation is in TypeScript, although the blog post below presents it in plain old JavaScript.
我们一直在使用一个简单的依赖注入容器,它使用 AMD 定义/要求 - 类似语法。最初的实现是在 TypeScript 中实现的,尽管下面的博客文章以普通的旧 JavaScript 呈现它。
http://blog.coolmuse.com/2012/11/11/a-simple-javascript-dependency-injection-container/
http://blog.coolmuse.com/2012/11/11/a-simple-javascript-dependency-injection-container/
It's pretty straightforward to define dependency relationships without requiring a bunch of configuration, and supports circular dependency resolution similar to requirejs.
定义依赖关系非常简单,不需要一堆配置,并且支持类似于requirejs的循环依赖解析。
Here's a simple example:
这是一个简单的例子:
// create the kernel
var kernel = new ServiceKernel();
// define service1
kernel.define("service1", function() {
// service1 has a function named foo
return {
foo: function () { return "foo"; }
}
});
// define service2, which depends on service1
kernel.define("service2", ["service1"], function(service1) {
// service2 has a function named foobar
return {
foobar : function() { return service1.foo() + "bar"; }
}
});
// get service2 instance
var service2 = kernel.require("service2");
service2.foobar(); // returns "foobar"
// get both service1 and service2 instances
kernel.require(["service1", "service2"], function(service1, service2) {
alert(service1.foo() + service2.foobar()); // displays foofoobar
});
回答by Edwin Ikechukwu Okonkwo
checkout https://github.com/typestack/typedi
结帐https://github.com/typestack/typedi
something like this is possible:
这样的事情是可能的:
import "reflect-metadata";
import {Service, Container} from "typedi";
@Service()
class SomeClass {
someMethod() {
}
}
let someClass = Container.get(SomeClass);
someClass.someMethod();

