---
# System prepended metadata

title: nestjs 的 Dependency Injection 概念
tags: [nest.js]

---

# nestjs 的 Dependency Injection 概念

## 目標

1. 介紹 Dependenecy Injection
2. 說明 nestjs 中的應用情境
## 什麼是 Dependency


![image](https://i.imgur.com/Urk8jhS.png)

假設一個應用服務 app 啟動時需要使用 queue service , db service, log service。這時就可以說 queue service,  db service, 與 log service 是 app 的依賴。也就是說 app 需要這些 service 才能運行起來。

以組合的關係來看就如下圖：

![image](https://i.imgur.com/qfwW6hl.png)


以 code 的角度來說

```typescript=
export class MapService {}

export class PathFinder {
	private mapService;
	constructor() {
		this.mapService = new MapService();
	}
}
```

代表

```mermaid
classDiagram
	MapService <.. PathFinder
	class MapService
	class PathFinder{
		-MapService mapService
	}	
```

## Dependency Injection 概念

以上面的範例中

因為 PathFinder 會需要 MapService 做建構

因此變成 PathFinder 生命周期會被綁定在 MapService 上

然而為了讓 PathFinder 降低對 MapService 的生命周期依賴

可以透過把 MapService 由 constructor 傳入已經生成好的 MapService 實體

這種方式稱為依賴注入

而更好的方式是把注入的類別做抽象化，也就是可以讓注入的實體只依賴於抽象類別或是介面

這樣彼此的相依程度會更加降低，以方便做測試隔離

## nestjs 的 Dependency Injection

目前在 Nestjs 框架中提供的依賴注入方式

目前在 nestjs 框架中提供的依賴注入方式有兩種

1. 建構子注入

```typescript=
@Injectable()
export class MapService {
}

export class PathFinder {
	constructor(private readonly mapService: MapService) {
		
	}
}
```

2. 屬性注入
```typescript=
@Injectable()
export class MapService {
}

export class PathFinder {
	@Inject(MapService) mapService: MapService;
}
```

這個 DI 容器特性讓 nestjs 的程式能夠讓程式元件間的耦合度降低
方便於測試以及對程式做修改


