繁体   English   中英

@inject() 在 tsyringe 的依赖注入中做了什么?

[英]What does the @inject() do in dependency injection with tsyringe?

我正在用tsyringe学习 DI。 我对 DI 的概念也完全陌生。

以下代码段有效,并且container.resolve(Foo)正确实例化了依赖项。

import "reflect-metadata";
import { injectable, container } from "tsyringe";

class Database {
  get() {
    return "got-stuff-from-database";
  }
}

@injectable()
class Foo {
  constructor(private database: Database) {}

  checkDb() {
    return this.database.get();
  }
}

const fooInstance = container.resolve(Foo);
console.log(fooInstance.checkDb());

//=> got-stuff-from-database

这是可以理解的。 但是下面的代码片段(主要取自他们的自述文件)既不适合我,我也无法理解,我也无法理解当我们拥有上述injectable装饰器时为什么需要inject 对不起,我在网上搜索并发现每个人都在使用它,就像每个人都已经知道它一样。

interface Database {}

@injectable()
class Foo {
  constructor(@inject("Database") private database?: Database) {}

  checkDb() {
    return 'stuff';
  }
}

const fooInstance = container.resolve(Foo);
console.log(fooInstance.checkDb());

所以要记住的主要事情是tsyringe是一个Typescript库。 当 Typescript 被编译为 Javascript 时,接口基本上不再存在(如您示例中的Database接口),因此类发生的 DI 魔术无法像往常一样完成。 文档是这样解释的:

接口在运行时没有类型信息,所以我们需要用@inject(...) 来装饰它们,以便容器知道如何解析它们。

它仍然不适合您的原因是因为您只告诉 DI 框架它必须查找在令牌"Database"下注册的某些内容的实例,但实际上没有任何注册在那里。 所以要让它工作,你仍然需要告诉tsyringe "Database"有一个与之关联的类或实例,如下所示:

container.register("Database", {
  useClass: SomeDatabaseImplementation
});

请注意,您仍然必须创建所述实现,因为您无法实例化接口。 为了更深入地了解,我建议您查看库的源代码,它很容易理解,并且可以让您更好地了解内部工作原理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM