从Aurelia依赖注入容器中显式请求新实例

时间:2018-02-28 18:21:02

标签: typescript dependency-injection aurelia

在Aurelia(+ TypeScript)......

有没有办法在上下文中直接引用容器(例如在视图模型中)并明确地“请求”新实例?

1 个答案:

答案 0 :(得分:3)

要在视图模型中获取容器,通常有3个选项:

1。注入容器

使用@inject(Container)装饰您的viewmodel,或者只需应用任何装饰器(这会使tsc发出类型元数据),并确保在构造函数中指定类型,如下所示:

constructor(private container: Container) {}

这是获取容器的推荐方法,因为它将为您提供作用于该特定视图模型的子容器。这意味着如果您请求ElementRouter之类的内容,您还可以获得范围为该视图模型的内容。

您注册到该容器的内容只能通过该容器或其子容器进行解析 - 而不是其兄弟姐妹或父母。

2。使用全局容器

总有一个“root”容器,您可以通过Container.instance静态属性访问代码中的任何位置。

对于某些生活在正常aurelia生命周期之外的组件,或者如果你真的需要root,这可能很有用。你可以避免这种情况,因为它会导致意大利面条代码。

3。 “滥用”路由器

我不一定会推荐这个,但每个配置的路由器上始终都有.container属性。这是作用域子路由器 - 如果将其注入视图模型的构造函数中,则会获得相同的路径。

一旦你有了对容器的引用:

致电container.get(Foo),仅从该容器中获取Foo的实例,或致电container.getAll(Foo)以获取该容器中所有Foo的列表它的父母,直到根。

  • 对于构造函数,它默认调用构造函数并以递归方式解析其依赖项(如果有的话)。然后它将实例存储为单例

  • 对于任何不是构造函数的东西(nullundefined除外),它默认存储值并在您再次使用相同的值调用它时返回它(不是特别有用,但是在最少没有错误。)

  • 对于nullundefined,它会引发错误。

终身和范围

有两种生命周期注册类型:

  • singleton为容器的生命周期提供相同的实例
  • 每次调用容器时,
  • transient都会提供一个新实例

singleton的生命周期进一步取决于它注册的容器的生命周期,对于典型的子容器,它是视图模型的生命周期。

API表面的其他部分基本上只是singletontransient的不同范围变体。

设置注册类型

这里有很多选择,我不会在这里讨论所有选项。与您相关的是直接容器API:

container.register...(key, fn)

之后,当您致电container.get(key)时,它将根据您刚刚设置的注册来解决依赖关系。你也可以在事后改变它 - 只会覆盖现有的解析器。

  • 单身人士:container.registerSingleton(Foo)

  • 实例(单身但你提供实例):container.registerInstance(Foo, new Foo(new Bar()))

  • 瞬态:container.registerTransient(Foo)

  • 自定义功能:container.registerHandler(Foo, (container, key, resolver) => new Foo(container.get(Bar))(适用于具有单身Foo的短暂Bar

还有其他选择,但这些是最常用的选项。

关于key, fn参数的最后说明:调用register(Foo)等同于调用register(Foo, Foo)。如果您不希望/没有对您要调用它的类名称的引用,也可以说register("foo", Foo)

能够打开调试器并说document.body.aurelia.container.get("foo")是我个人觉得有时调试非常方便的事情:)