Dependency Injection (DI) คือ Pattern การส่ง Dependency จากภายนอกเข้าไปให้ Class แทนการสร้างเองภายใน Class ทำให้โค้ดแยกหน้าที่ชัดเจน เปลี่ยน implementation ได้ง่าย และทดสอบด้วย Mock ได้สะดวก
%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#fabd2f", "primaryTextColor": "#282828", "primaryBorderColor": "#b57614", "lineColor": "#7c6f64", "secondaryColor": "#83a598", "tertiaryColor": "#b8bb26", "background": "#fbf1c7", "mainBkg": "#ebdbb2", "fontFamily": "Tahoma, sans-serif"}}}%%
flowchart LR
subgraph Era1["ยุคสร้างเอง / Manual Creation"]
A["new Service()
ผูกแน่นกับ Class"]
end
subgraph Era2["ยุค DI Pattern / Dependency Injection"]
B["Constructor Injection
ส่ง Dependency จากภายนอก"]
C["Mock Friendly
ทดสอบง่ายขึ้น"]
end
subgraph Era3["ยุค Angular Injector / Angular DI"]
D["@Injectable
ลงทะเบียน Service"]
E["Injector Hierarchy
Root Module Component"]
end
A --> B --> C --> D --> E
@Injectable({ providedIn: 'root' }) ลงทะเบียน Service ระดับ Globalconstructor(private service: MyService) {}providedIn: 'root' มักได้ Singleton หนึ่ง Instance ทั้งแอปproviders ใน Component ทำให้ Component และลูกมี Service Instance เฉพาะของตัวเอง| วิธีลงทะเบียน | Scope | Instance | เหมาะกับ |
|---|---|---|---|
providedIn: 'root' |
ทั้งแอป | โดยมาก 1 Instance | Service ทั่วไป, API, Shared State |
providers ใน NgModule |
ระดับ Module | ตาม Module | Feature Module เฉพาะ |
providers ใน Component |
Component Tree | Instance ใหม่ | State เฉพาะหน้าจอ |
%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#fabd2f", "primaryTextColor": "#282828", "primaryBorderColor": "#b57614", "lineColor": "#7c6f64", "secondaryColor": "#83a598", "tertiaryColor": "#b8bb26", "background": "#fbf1c7", "mainBkg": "#ebdbb2", "fontFamily": "Tahoma, sans-serif"}}}%%
flowchart TD
A["Root Injector
ตัวฉีดระดับแอป"] --> B["Module Injector
ตัวฉีดระดับโมดูล"]
B --> C["Component Injector
ตัวฉีดระดับคอมโพเนนต์"]
C --> D["Component Class
รับ Service ผ่าน constructor"]
D --> E["Service Dependency
ตรรกะหรือ API"]
// logger.service.ts
// Service นี้ใช้บันทึกข้อความ และลงทะเบียนใน root injector
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class LoggerService {
log(message: string): void {
console.log(`[LOG] ${message}`);
}
}
// course.component.ts
// Component รับ LoggerService ผ่าน constructor แทนการ new เอง
import { Component } from '@angular/core';
import { LoggerService } from './logger.service';
@Component({
selector: 'app-course',
template: `<button (click)="save()">Save</button>`
})
export class CourseComponent {
constructor(private logger: LoggerService) {}
save(): void {
this.logger.log('Course saved');
}
}
// ตัวอย่างการใช้งาน:
// <app-course></app-course>
LoggerServiceLoggerService ใน Unit Test แบบง่าย