多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
> 重要提示: **不要忘记用`@Service`装饰器声明你的类!**被注入的和请求依赖的那些都应该被声明。 ***** ## 注册依赖关系 有三种方法来注册你的依赖关系。 * 用`@Service()`装饰器注解一个类([链接]()) * 用`Token`注册一个值 * 用一个字符串标识符来注册一个值 `Token`和字符串标识符可以用来注册类以外的其他值。`Token`和字符串标识符都可以注册任何类型的值,包括除`undefined`之外的原始值。它们必须在容器上用`Container.set()`函数设置,然后才能通过`Container.get()`请求它们。 ``` import 'reflect-metadata'; import { Container, Inject, Service, Token } from 'typedi'; const myToken = new Token('SECRET_VALUE_KEY'); Container.set(myToken, 'my-secret-value'); Container.set('my-config-key', 'value-for-config-key'); Container.set('default-pagination', 30); // 在你应用的其他地方 const tokenValue = Container.get(myToken); const configValue = Container.get('my-config-key'); const defaultPagination = Container.get('default-pagination'); ``` ***** ## 注入依赖 有三种方法可以注入你的依赖关系。 * 通过类的构造函数参数自动注入 * 用`@Inject()`装饰器来注解类属性 * 直接使用`Container.get()`来请求一个类、`Token`或字符串标识符的实例。 ### 构造函数参数注入 任何已经用`@Service()`装饰器标记的类,它的构造器属性将会被自动注入正确的依赖关系。 **TypeDI将用于解决依赖关系的容器实例插入到构造函数的最后一个参数中。** ``` import 'reflect-metadata'; import { Container, Inject, Service } from 'typedi'; @Service() class InjectedClass {} @Service() class ExampleClass { constructor(public injectedClass: InjectedClass) {} } const instance = Container.get(ExampleClass); console.log(instance.injectedClass instanceof InjectedClass); // 输出为true,因为TypeDI将InjectedClass的实例分配给了属性。 ``` ### 属性注入 当父类被TypeDI初始化时,任何被`@Inject`装饰器标记的属性将被自动分配给该类的实例。 ``` import 'reflect-metadata'; import { Container, Inject, Service } from 'typedi'; @Service() class InjectedClass {} @Service() class ExampleClass { @Inject() injectedClass: InjectedClass; } const instance = Container.get(ExampleClass); console.log(instance.injectedClass instanceof InjectedClass); // 输出为true,因为InjectedClass的实例已经被TypeDI分配到`injectedClass`属性中。 ``` ### 使用`Container.get()` `Container.get()`函数可以直接用来请求一个目标类型的实例。TypeDI将解析并初始化所有对目标类的依赖。`Container.get()`可以被用来请求: * 一个可构造的值(类定义),它将返回类的实例 * `Token`,它将返回为该Token注册的值 * 字符串,它将返回用该名称注册的值 ``` import 'reflect-metadata'; import { Container, Inject, Service, Token } from 'typedi'; const myToken = new Token('SECRET_VALUE_KEY'); @Service() class InjectedClass {} @Service() class ExampleClass { @Inject() injectedClass: InjectedClass; } /** Tokens必须在容器中明确设置所需的值 */ Container.set(myToken, 'my-secret-value'); /** 字符串标识符必须在容器中明确设置为所需的值. */ Container.set('my-dependency-name-A', InjectedClass); Container.set('my-dependency-name-B', 'primitive-value'); const injectedClassInstance = Container.get(InjectedClass); // 可以请求一个没有依赖关系的类 const exampleClassInstance = Container.get(ExampleClass); // 可以请求一个有依赖关系的类,并且依赖关系将被解决。 const tokenValue = Container.get(myToken); // tokenValue 将是 'my-secret-value' const stringIdentifierValueA = Container.get('my-dependency-name-A'); // stringIdentifierValueA 将是 InjectedClass 的实例。 const stringIdentifierValueB = Container.get('my-dependency-name-B'); //stringIdentifierValueB 将是 'primitive-value' ``` ***** ## 单例与暂存类 每个注册的 Service 默认都是一个单例。这意味着对`Container.get(MyClass)`的重复调用将返回同一个实例。如果这不是我们想要的行为,可以通过`@Service()`装饰器将一个类标记为瞬时的: ``` import 'reflect-metadata'; import { Container, Inject, Service } from 'typedi'; @Service({ transient: true }) class ExampleTransientClass { constructor() { console.log('I am being created!'); // 这将被输出两次 } } const instanceA = Container.get(ExampleTransientClass); const instanceB = Container.get(ExampleTransientClass); console.log(instanceA !== instanceB); // prints true ```