`@Inject()`装饰器是一个属性和参数装饰器,用于解决对一个类的属性或构造函数参数的依赖。默认情况下,它推断出属性或参数的类型,并初始化一个检测到的类型的实例,然而,这种行为可以通过指定一个自定义的可构造类型、Token或已命名`Service`作为第一个参数来覆盖。
*****
## 属性注入
这个装饰器在需要类实例的属性上是强制性的(也就是说:如果没有这个装饰器,这个属性将保持未定义)。属性的类型是自动推断出来的,所以不需要定义所需的值作为装饰器的参数。
```
import 'reflect-metadata';
import { Container, Inject, Service } from 'typedi';
@Service()
class InjectedExampleClass {
print() {
console.log('I am alive!');
}
}
@Service()
class ExampleClass {
@Inject()
withDecorator: InjectedExampleClass;
withoutDecorator: InjectedExampleClass;
}
const instance = Container.get(ExampleClass);
/**
* `instance`变量是一个ExampleClass实例
* 其`withDecorator`属性包含一个InjectedExampleClass实例
* 而`withoutDecorator`属性未被定义
*/
console.log(instance);
instance.withDecorator.print();
// 输出"I am alive!" (InjectedExampleClass.print 方法)
console.log(instance.withoutDecorator);
// 输出 undefined, 因为这个属性没有用@Inject装饰器标记
```
*****
## 构造函数注入
当一个类被标记为`@Service`装饰器时,在构造器注入中不需要`@Inject`装饰器。TypeDI将自动推断并为每个构造函数参数注入正确的类实例。然而,`@Inject`可以被用来覆盖注入的类型。
```
import 'reflect-metadata';
import { Container, Inject, Service } from 'typedi';
@Service()
class InjectedExampleClass {
print() {
console.log('I am alive!');
}
}
@Service()
class ExampleClass {
constructor(
@Inject()
public withDecorator: InjectedExampleClass,
public withoutDecorator: InjectedExampleClass
) {}
}
const instance = Container.get(ExampleClass);
/**
* `instance'变量是一个ExampleClass实例
* 它同时具有
`withDecorator`和`withoutDecorator`属性
* 都包含一个
InjectedExampleClass实例。
*/
console.log(instance);
instance.withDecorator.print();
// 输出 "I am alive!" (InjectedExampleClass.print function)
instance.withoutDecorator.print();
// 输出 "I am alive!" (InjectedExampleClass.print function)
```
*****
## 明确请求目标类型
默认情况下,TypeDI将尝试推断属性和参数的类型并注入适当的类实例。当需要时(例如:属性类型是一个接口),有三种方式来覆盖注入值的类型。
* 通过 `@Inject(() => type)` 其中`type`是一个可构建的值(例如:一个类定义)。
* 通过 `@Inject(myToken) `其中`myToken`是一个`Token`类的实例
* 通过 `@Inject(serviceName)` 其中`serviceName`是一个字符串,已经通过`Container.set(serviceName, value)`注册过了。
```
import 'reflect-metadata';
import { Container, Inject, Service } from 'typedi';
@Service()
class InjectedExampleClass {
print() {
console.log('I am alive!');
}
}
@Service()
class BetterInjectedClass {
print() {
console.log('I am a different class!');
}
}
@Service()
class ExampleClass {
@Inject()
inferredPropertyInjection: InjectedExampleClass;
/**
* 我们告诉TypeDI,用`BetterInjectedClass`类初始化。
* 不管推断的类型是什么。
*/
@Inject(() => BetterInjectedClass)
explicitPropertyInjection: InjectedExampleClass;
constructor(
public inferredArgumentInjection: InjectedExampleClass,
/**
* 我们告诉TypeDI,用`BetterInjectedClass`类初始化。
* 不管推断的类型是什么。
*/
@Inject(() => BetterInjectedClass)
public explicitArgumentInjection: InjectedExampleClass
) {}
}
/**
* `instance`变量是一个 ExampleClass 的实例,同时具有
* - `inferredPropertyInjection` 和 `inferredArgumentInjection` 属性
* 都包含一个`InjectedExampleClass`实例
* - `explicitPropertyInjection`和`explicitArgumentInjection`属性
* 都包含一个`BetterInjectedClass'实例。
*/
const instance = Container.get(ExampleClass);
instance.inferredPropertyInjection.print();
// prints "I am alive!" (InjectedExampleClass.print function)
instance.explicitPropertyInjection.print();
// prints "I am a different class!" (BetterInjectedClass.print function)
instance.inferredArgumentInjection.print();
// prints "I am alive!" (InjectedExampleClass.print function)
instance.explicitArgumentInjection.print();
// prints "I am a different class!" (BetterInjectedClass.print function)
```