我知道如何使用@inject
类装饰器使用aurelia工厂解析器:
@inject(Factory.of(Foo))
export class NeedsFoo {
foo: Foo;
constructor(fooFactory: () => Foo) {
this.foo = fooFactory(config);
}
}
config
是初始化Foo实例所需的一些配置状态,无法注入。
但是在一些较大的视图模型中,@autoinject
更好更容易添加/删除依赖项,但我无法弄清楚如何使用参数装饰器来实现相同的功能。
解析器简要记录here,没有工厂解析器属性的示例。一个相关的错误是here,但我无法从中找出用法。有一堆SO问题,但它们都引用@inject(Factory.of(...))
如果我尝试以下操作,那么fooFactory就是一个空对象{}
:
@autoinject()
export class NeedsFoo {
foo: Foo;
constructor(@factory(Foo) fooFactory) {
this.foo = fooFactory(config);
}
}
对bug讨论的评论说:
interface FooFactory {
new (config: any): Foo;
}
class NeedsFoo {
foo: Foo;
constructor(@factory(Foo) fooFactory: FooFactory) {
this.foo = new fooFactory(config); // error!
}
}
但标记的行以TypeError: fooFactory is not a constructor.
(它是一个空对象)
我可以使用参数装饰器和自动注入来为Aurelia注入类的工厂吗?
编辑:将 deps 重命名为 config ,因此看起来我没有传递注入的依赖项。
编辑2:fooFactory是一个空对象,不是未定义的
答案 0 :(得分:3)
你非常接近。只需在第二个示例中将@autoinject()
添加到NeedsFoo,摆脱deps
参数,如果它有自己的deps,也不要忘记将@autoinject()
放在Foo上。
进一步阐明其工作方式/原因,并消除一些误解:
在类上放置任何装饰器将使tsc为该类发出类型元数据。如果类中没有其他装饰器,则只能使用autoinject。已经是@customElement()
了吗?无需@autoinject()
。
您从不需要将依赖项传递给工厂函数。它们由工厂功能内的容器检索。
工厂函数不是类构造函数,它是构造函数。将其作为fooFactory()
或new fooFactory()
调用具有相同的效果:它调用函数并返回函数返回的任何内容。
接口不能编译为javascript。使用接口作为参数类型永远不会使DI工作。 : FooFactory
这里跟: any
一样。这仅适用于intellisense。
使用@factory()
时,传递给函数的类型将取代参数本身的类型。参数的类型将被忽略。
这为您提供了几种替代实现。
给出以下类Foo
@autoinject()
export class Foo {
public bar: Bar;
constructor(bar: Bar) {
this.bar = bar;
}
}
任何这些类NeedsFoo:
@autoinject()
export class NeedsFoo {
public foo: Foo;
constructor(@factory(Foo) fooFactory: any) {
this.foo = new fooFactory();
}
}
@customElement("needs-foo")
export class NeedsFoo {
public foo: Foo;
constructor(@factory(Foo) fooFactory: FooFactory) {
this.foo = new fooFactory();
}
}
@autoinject()
export class NeedsFoo {
public foo: Foo;
constructor(@factory(Foo) fooFactory: any) {
this.foo = fooFactory();
}
}
@autoinject()
export class NeedsFoo {
public foo: Foo;
constructor(@factory(Foo) fooFactory: FooFactory ) {
this.foo = new fooFactory();
}
}
interface FooFactory {
new(): Foo;
}
他们(以及他们的不同组合)都是相同的,并为您提供了Foo
的实例。