简体   繁体   English

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

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

I'm learning DI with tsyringe .我正在用tsyringe学习 DI。 I'm also totally new to the concept of DI.我对 DI 的概念也完全陌生。

The following snippet works and the container.resolve(Foo) properly instantiate the dependencies.以下代码段有效,并且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

This is understandable.这是可以理解的。 But the snippet below (mostly taken from their readme) is neither working for me nor I can understand, and nor I can understand why we need inject when we have the above injectable decorator.但是下面的代码片段(主要取自他们的自述文件)既不适合我,我也无法理解,我也无法理解当我们拥有上述injectable装饰器时为什么需要inject I'm sorry I searched online and found everyone is using it like everyone already know about it.对不起,我在网上搜索并发现每个人都在使用它,就像每个人都已经知道它一样。

interface Database {}

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

  checkDb() {
    return 'stuff';
  }
}

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

So the main thing to keep in mind is that tsyringe is a Typescript library.所以要记住的主要事情是tsyringe是一个Typescript库。 When Typescript gets compiled to Javascript the interfaces are basically not there anymore (like the Database interface in your example) so the DI magic that happens with the classes can't be done as usual.当 Typescript 被编译为 Javascript 时,接口基本上不再存在(如您示例中的Database接口),因此类发生的 DI 魔术无法像往常一样完成。 The documentation explains it like so: 文档是这样解释的:

Interfaces don't have type information at runtime, so we need to decorate them with @inject(...) so the container knows how to resolve them.接口在运行时没有类型信息,所以我们需要用@inject(...) 来装饰它们,以便容器知道如何解析它们。

The reason it's still not working for you is because you have only told the DI framework that it has to look for an instance of something registered under the token "Database" but there is actually nothing registered there.它仍然不适合您的原因是因为您只告诉 DI 框架它必须查找在令牌"Database"下注册的某些内容的实例,但实际上没有任何注册在那里。 So to make it work you still need to tell tsyringe that "Database" has a class or instance associated to it like so:所以要让它工作,你仍然需要告诉tsyringe "Database"有一个与之关联的类或实例,如下所示:

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

Note that you still would have to create said implementation because you can't instantiate interfaces.请注意,您仍然必须创建所述实现,因为您无法实例化接口。 For deeper understanding I would recommend having a look at the source code of the library, it's fairly simple to understand and gives you a much better understanding of the inner workings.为了更深入地了解,我建议您查看库的源代码,它很容易理解,并且可以让您更好地了解内部工作原理。

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

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