使用小足迹的TypeScript依赖注入

3

我是一名C#程序员,对nodejs和typescript比较陌生。 我希望在项目中使用依赖注入,发现最流行的包是inversify。

我已开始使用它,但不喜欢需要到处添加装饰器的方式。

例如,我不太喜欢在构造函数参数前面添加@inject:

public constructor(
    @inject(TYPES.Weapon) katana: Weapon,
    @inject(TYPES.ThrowableWeapon) shuriken: ThrowableWeapon
)

这意味着每个类都必须知道TYPES对象...

我不理解为什么@inject需要字符串文字,而不能基于类型进行注入...

有更简洁的方法吗?


1
“仅基于类型” --- 我不熟悉那个库,但是TS本身在运行时不存在。 - zerkms
1个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
3
与严格类型语言不同,TypeScript 类型在运行时不存在。可以在运行时使用类型信息进行依赖注入,但是受限制。通过使用 emitDecoratorMetadata TypeScript 选项,可以获取构造函数参数类型并将其用于 DI。 示例是 injection-js,它是从库中提取出来的 Angular 注入器,可用于独立使用。只需要在启用 DI 的类上使用 @Injectable 装饰器,@Inject 参数装饰器是可选的。 限制是只能通过类实例注入:
constructor(foo: FooClass) {}

泛型被忽略并丢弃:

constructor(foo: FooClass<Bar>) {}
其他类型将被忽略,结果会导致DI错误:
constructor(foo: fooSymbol) {}

constructor(foo: 'foo string provider') {}

同样 适用于InversifyJS:

对于具体的注入,您可以像往常一样定义构造函数参数,而不使用@inject装饰器。

InversifyJS还支持TypeScript的构造函数赋值,因此您可以在参数中具有私有或受保护的访问修饰符,容器将毫无问题地注入依赖项

如果它们是类,可以省略@inject对于WeaponThrowableWeapon,但在所列示例中{{link2:TYPES.Weapon是一个符号,Weapon是一个在运行时不存在的接口}}, 因此@inject是必需的。


我明白了...所以如果我想使用接口,我必须使用装饰器。 - Mithir
是的。或者你可以坚持使用类,因为它们允许你省略 @inject。在 TS 中,类充当接口,但也存在于运行时。 - Estus Flask
你指的是 "n个TS类既可以作为接口,又可以在运行时存在" 是什么意思? - Mithir
可以使用 class Foo {} 作为类型(接口),例如 let foo: Foo,但它仍然是一个类(函数),可以在运行时使用 foo = new Foo。这就是 DI 库中使用的质量,这些库在答案中列出。如果 Foointerface Foo {},则无法做到这一点。这就是 TS 与 C# 的区别。 - Estus Flask

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,