`@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)
```