เนื้อหานี้เราจะมาดูกันต่อในเรื่องของการใช้งาน service ที่เป็น Injector ซึ่งเรา
ได้รู้จักวิธีการขึ้นทะเบียนใน provider ไปแล้วในตอนที่ผ่านมา
(ทบทวนบทความได้ที่)
ตั้งค่า Injector กำหนด service class ใน provider เพื่อใช้งานใน Angular
https://www.ninenik.com/content.php?arti_id=782 via @ninenik
ในเนื้อหานี้ เราจะทำการสร้าง service class ขึ้นมาอีกตัว เพื่อที่จะนำไปใช้งาน
ใน StaffService class อีกทีหนึ่ง
ให้สร้างไฟล์ชื่อ logger.service.ts โดยเราจะสร้างไว้ในโฟลเดอร์ app
ไฟล์ logger.service.ts
import { Injectable } from '@angular/core'; @Injectable() export class Logger { logs: string[] = []; // กำหนดตัวแปร array แบบ string log(message: string) { // ฟังก์ชั่น log() this.logs.push(message); // รับค่าข้อความและเพิ่มไปใน array console.log(message); // แสดงข้อความใน console } }
เราจะสมมติให้ Logger class ในไฟล์ logger.service.ts นี้ทำหน้าที่ในการบันทึก
ข้อมูลการเรียกใช้งานภายใน App เช่น สมมติ เมื่อมีการเรียกใช้งาน StaffService ก็ให้ Logger
ทำการบันทึกข้อความว่า ตอนนี้มีการเรียกดูข้อมูลของ staff เกิดขึ้น แบบนี้เป็นต้น
และเนื่องจาก Logger class นี้ เราสามารถนำไปใช้กับส่วนอื่นๆ ภายใน App ได้ ดังนั้น
อย่างที่เราทราบ ก่อนเรียกใช้งาน service เราต้องทำการขึ้นทะเบียนใน provider ก่อน
ซึ่งในกรณีของ Logger เราจะขึ้นทะเบีบน provider ไว้ใน @NgModule เพื่อให้สามารถ
เรียกใช้งานได้ในทุกส่วนของ App โดยให้เราทำการกำหนดค่าในไฟล์ app.module.ts ดังนี้
ไฟล์ app.module.ts
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { UserComponent } from './components/user.component'; import { StaffFormComponent } from './components/staff-form.component'; import { StaffListComponent } from './components/staff-list.component' import {Logger } from './logger.service' @NgModule({ imports: [ BrowserModule, FormsModule ], declarations: [ AppComponent, UserComponent, StaffFormComponent, StaffListComponent ], providers:[ Logger ], bootstrap: [ AppComponent ] }) export class AppModule { }
หลังจากขึ้นทะเบียน service class ใน provider เรียบร้อยแล้ว เราก็สามารถที่จะเรียกใช้งาน
Logger จากส่วนไหนภายใน App ก็ได้ ในที่นี้จุดประสงค์ของเรา คือจะทำการนำเข้าไปใน
StaffService class ที่เป็น service ที่เราได้เรียกใช้งานใน StaffListComponent
ลักษณะที่กล่าวข้างต้น ก็คือการเรียกใช้งาน service หนึ่ง ในอีก service หนึ่งอีกที ดังนี้
ให้เราเปิดไฟล์ staff.service.ts ซึ่งโค้ดเดิมเป็นดังนี้
ไฟล์ staff.service.ts
import { Injectable } from '@angular/core'; import { STAFFS } from './mock-staffs'; @Injectable() export class StaffService { getStaffs() { return STAFFS; } }
ปรับใหม่เป็นดังนี้
import { Injectable } from '@angular/core'; import { STAFFS } from './mock-staffs'; import { Logger } from '../logger.service' @Injectable() export class StaffService { constructor(private logger: Logger) { } getStaffs() { this.logger.log('เรียกดูข้อมูล staff ...'); return STAFFS; } }
จากโค้ดข้างต้น จะเห็นว่ามีการ import Logger มาใช้งานใน StaffService และ
ใช้ฟังก์ชั่น constructor() ในการสร้างตัวแปรชื่อ logger อ้างอิงจาก Logger class
แบบ private ใช้เฉพาะภายใน StaffService class
โดยในคำสั่ง getStaffs() ให้ตัวแปร logger เรียกใช้คำสั่ง log() คือให้นำข้อความว่า
"เรียกดูข้อมูล staff ..." บันทึกเข้าไปใน array ข้อมูล logs ตามโครงสร้างคำสั่งในไฟล์
logger.service.ts
จะเห็นว่าเมื่อฟังก์ชั่นคำสั่ง getStaffs() ถูกเรียกใช้งาน ก่อนที่จะมีการ return ค่าตัวแปร
STAFFS ก็มีการเรียก service class ที่ชื่อ Logger ให้ทำงานด้วยทุกๆ ครั้ง
ดูผลลัพธ์ใน console ประกอบ ดังรูป
จากรูปจะเห็นว่าเมื่อมีการเรียกใช้คำสั่ง getStaffs() ในไฟล์ staff.service.ts ใน service class แรก
เพื่อเรียกดูรายชื่อ staff ก็มีการเรียกใช้คำสั่ง log() ในไฟล์ logger.service.ts ใน service class
ตัวที่สองที่ถูกดึงมาใช้งานใน service class ตัวแรกอีกที โดยในตัวอย่างเป็นการจำลองการแสดงข้อความ
ใน console ด้วย console.log() ที่กำหนดไว้ใน Logger class
Provider และการกำหนดใน Provider เพิ่มเติม
เราจะกลับกันมาที่ไฟล์ app.module.ts มาดูในส่วนของการกำหนด provider ให้กับ service class
เพิ่มเติม ดังนี้
service class ที่นำมาทำการขึ้นทะเบียน provider ก่อนที่นำเข้าไปใช้งานในส่วนอื่นๆ ของ App
เราจะเรียกการขึ้นทะเบียนของ service class ลักษณะนี้ว่า Injector provider
provider จะทำหน้าที่ในการสร้างตัวแปรอ้างอิง service class นั้นๆ สำหรับเรียกใช้งาน โดยรูปแบบ
ที่เราได้กำหนดไปข้างต้นที่ผ่านมาในไฟล์ app.module.ts คือ
providers:[ Logger ],
ลักษณะการขึ้นทะเบียน provider ข้างต้นเป็นการกำหนดค่า Logger ซึ่งเป็นชื่อของ service class
ลงใน providers array metadata นอกจากรูปแบบข้างต้นแล้วเราสามารถกำหนด provider
ในรูปแบบอื่นๆ ได้ เช่นการกำหนดเป็นแบบ Object เป็นต้น มาดูตัวอย่าง เปรียบเทียบกัน
รูปแบบการกำหนดแบบ Array class
providers:[ Logger ],
มาจากรูปแบบเต็มที่เป็นแบบ Object ดังนี้
providers:[ { provide: Logger, useClass: Logger } ],
Object ข้างต้นมี property ที่ชื่อ provide และ useClass การกำหนดข้างต้น ความหมายก็คือ
ให้ใช้ class ชื่อ Logger ในตัวแปรอ้างอิงที่ชื่อ Logger
provide คือ ชื่ออ้างอิงสำหรับเป็น Injector Provider
useClass คือ ชื่อ service class ที่จะใช้งาน
การแทนที่ด้วย class provider อื่น
จากรูปแบบการขึ้นทะเบียน provider ข้างต้น ทำให้เราสามารถกำหนด property ที่ชื่อ useClass
เป็นค่าอื่นได้ สมมติเป็น
providers:[ { provide: Logger, useClass: EvenBetterLogger } ],
อย่างเช่น ในบางครั้ง เราต้องการใช้งาน class อื่นในการใช้งาน service
ให้เราเพิ่ม service class เสริมเข้าไปในไฟล์ logger.service.ts โดยเป็น class ชื่อ
EvenBetterLogger สืบทอดมาจาก Logger class อีกที ดังนี้
ไฟล์ logger.service.ts
import { Injectable } from '@angular/core'; @Injectable() export class Logger { logs: string[] = []; // กำหนดตัวแปร array แบบ string log(message: string) { // ฟังก์ชั่น log() this.logs.push(message); // รับค่าข้อความและเพิ่มไปใน array console.log(message); // แสดงข้อความใน console } } @Injectable() export class EvenBetterLogger extends Logger { log(message: string) { console.log(message+" In EvenBetterLogger class"); super.log("ส่งข้อความไปในฟังก์ชั่น log() ของ Logger class"); } }
เราได้สร้าง EvenBetterLogger class ที่สืบทอดมาจาก Logger class อีกที โดย
มีคำสั่งที่ชื่อ log(); เป็นชื่อเดียวกันกับคำสั่งใน Logger class ทั้งนี้เพื่อที่เราจะได้ไม่ต้อง
ไปแก้ไขไฟล์ staff.service.ts ที่มีการเรียกใช้คำสั่ง log() อยู่แล้ว
ส่วนบรรทัด
super.log("ส่งข้อความไปในฟังก์ชั่น log() ของ Logger class");
เป็นการให้ไปเรียกคำสั่ง log() ของ Logger class สังเกตได้จากการใช้คำว่า super
super ก็จะหมายถึง class ที่ EvenBetterLogger class ทำการสืบทอดมา ซึ่งก็คือ
Logger class
การทำงานของคำสั่ง log() ใน EvenBetterLogger class คือเราให้แสดง ข้อความ
ผ่านทาง console ด้วยคำสั่ง console.log() โดยใช้แสดงค่าของข้อความที่กำหนด
ในไฟล์ staff.service.ts บรรทัด
this.logger.log('เรียกดูข้อมูล staff ...');
ข้อความนี้ "เรียกดูข้อมูล staff ..." จะถูกส่งเข้าไปในคำสั่ง log() ใน EvenBetterLogger class
แล้วต่อด้วยคำว่า "In EvenBetterLogger class" จากนั้นแสดงออกทาง console
ซึ่งจากเดิม คำสั่ง this.logger.log(); เป็นการเรียกจาก Logger class ถ้าเรากำหนด useClass
ใน provider เป็น Logger แต่กรณีนี้ เราเปลี่ยน useClass ใน provider เป็น EvenBetterLogger
ดังนั้นคำสั่ง this.logger.log(); จึงการไปทำงานคำสั่ง log() ใน EvenBetterLogger class แทน
หมายเหตุ: ปกติเราควรสร้างไฟล์เป็นไฟล์แยก แต่ในที่นี้เราจะลดขั้นตอนเพื่อให้เห็นภาพ
ง่ายขึ้น และไฟล์ไม่มากป้องกันความสับสน
ต่อไปให้เราแก้ไขไฟล์ app.module.ts เพิ่ม EvenBetterLogger class ในส่วนของการ import
และเปลี่ยน useClass เป็น EvenBetterLogger
ไฟล์ app.module.ts
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { UserComponent } from './components/user.component'; import { StaffFormComponent } from './components/staff-form.component'; import { StaffListComponent } from './components/staff-list.component' import { Logger,EvenBetterLogger } from './logger.service' @NgModule({ imports: [ BrowserModule, FormsModule ], declarations: [ AppComponent, UserComponent, StaffFormComponent, StaffListComponent ], providers:[ { provide: Logger, useClass: EvenBetterLogger } ], bootstrap: [ AppComponent ] }) export class AppModule { }
ทดสอบรันไฟล์ดูผลลัพธ์ จะได้เป็นดังนี้
การใช้ class provider ด้วยชื่อเรียกอื่น
สมมติเรามีการใช้งาน Logger class อยู่เดิมแล้ว และมี NewLogger class เป็น class ใหม่ที่
มีลักษณะเหมือนกับ Logger class (มี interface พวกคำสั่ง ตัวแปร หรือ property คล้ายกัน) แต่เนื่องจากเหตุผลหรือความจำเป็นบางอย่าง ทำให้เรา
ไม่สามารถไปแก้ไขส่วนของ Component ที่มีการใช้ตัวแปรอ้างอิงชื่อ Logger ไปแล้วเป็นค่าใหม่ว่า
NewLogger ได้
สมมมติเราให้ไฟล์ logger.service.ts เป็นดังนี้
ไฟล์ logger.service.ts
import { Injectable } from '@angular/core'; @Injectable() export class Logger { logs: string[] = []; // กำหนดตัวแปร array แบบ string log(message: string) { // ฟังก์ชั่น log() this.logs.push(message); // รับค่าข้อความและเพิ่มไปใน array console.log(message); // แสดงข้อความใน console } } @Injectable() export class NewLogger { logs: string[] = []; // กำหนดตัวแปร array แบบ string log(message: string) { // ฟังก์ชั่น log() console.log("use NewLogger class"); this.logs.push(message); // รับค่าข้อความและเพิ่มไปใน array console.log(message); // แสดงข้อความใน console } } @Injectable() export class EvenBetterLogger extends Logger { log(message: string) { console.log(message+" In EvenBetterLogger class"); super.log("ส่งข้อความไปในฟังก์ชั่น log() ของ Logger class"); } }
โดยเราต้องการให้เมื่อไหร่ก็ตามที่ตัวแปรอ้างอิงชื่อ Logger ถูกเรียกใช้งาน ให้หมายถึงการใช้งาน
จาก NewLogger class ที่มีอยู่แล้วแทน ทั้งนี้ก็เพื่อต้องการนำเข้า NewLogger class เพียง class
เดียวในชื่อตัวแปรอ้างอิง NewLogger หรือ Logger
กล่าวคือถ้า ถ้ามีการเรียกใช้ตัวแปรอ้างอิงที่ชื่อ
- NewLogger ก็จะหมายถึงการใช้ NewLogger class และเช่นกัน
- Logger ก็จะหมายถึงการใช้ NewLogger class ที่มีการนำเข้ามาแล้วจากตัวแปรอ้างอิง NewLogger
ดังนั้น Logger เป็นชื่อเรียก NewLogger ที่ใช้ NewLogger class เดียวกัน
ซึ่งในกรณีลักษณะแบบนี้ เราจะไม่ใช้วิธีการกำหนดโดยใช้ userClass แต่จะใช้เป็น
useExisting ในการขึ้นทะเบียน provider แทน ดังนี้
ไฟล์ app.module.ts
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { UserComponent } from './components/user.component'; import { StaffFormComponent } from './components/staff-form.component'; import { StaffListComponent } from './components/staff-list.component'; import { Logger,EvenBetterLogger,NewLogger } from './logger.service'; @NgModule({ imports: [ BrowserModule, FormsModule ], declarations: [ AppComponent, UserComponent, StaffFormComponent, StaffListComponent ], providers:[ NewLogger, { provide: Logger, useExisting: NewLogger } ], bootstrap: [ AppComponent ] }) export class AppModule { }
ซึ่งถ้าเราใช้แบบ useClass ดังโค้ดนี้
providers:[ NewLogger, { provide: Logger, useClass: NewLogger } ],
รูปแบบนี้ถ้าขยายแบบเต็มรูปแบบจะได้เป็น
providers:[ { provide: NewLogger, useClass: NewLogger } { provide: Logger, useClass: NewLogger } ],
กรณีนี้จะกลายเป็นการสร้างตัวแปรอ้างอิงของ NewLogger class ขึ้นมาสองตัว
ในชื่อ NewLogger และ Logger แต่สำหรับวิธีการใช้โดยกำหนด useExisting
ที่อธิบายไปก่อนหน้า โดยรูปแบบเต็มจะเป็นดังนี้
providers:[ { provide: NewLogger, useClass: NewLogger } { provide: Logger, useExisting: NewLogger } ],
จะเป็นการสร้างตัวแปรอ้างอิงของ NewLogger class ขึ้นมาตัวเดียว
โดยสามารถใช้ชื่อว่า NewLogger
โดยตัวแปรอ้างอิงชื่อ Logger จะเป็นชื่อเรียกของตัวแปรอ้างอิง NewLogger อีกที
ไม่ได้เป็นการสร้างตัวแปรอ้างอิงใหม่
มาดูผลลัพธ์ทดสอบรัน จะได้ผลลัพธ์ดังรูป
การนำเข้า service และการใช้งานใน class provider
เรามาดูเพิ่มเติมเกี่ยวกับ class ที่เรากำหนดใน provider โดยสมมติการนำเข้า service
มาใช้กับ class ที่เรากำหนดใน provider ว่าจะมีการใช้งานในลักษณะใด
สมมติเราสร้างไฟล์ชื่อ beststaff.service.ts ไว้ในโฟลเดอร์ components ดังรูป
ไฟล์ beststaff.service.ts
import { Injectable } from '@angular/core'; import { STAFFS } from './mock-staffs'; @Injectable() export class BestStaffService { getBestStaff() { // สมมติเราให้คืนค่าเป็น ชื่อข้อมูล staff คนแรก return STAFFS[0]; } }
จากนั้นให้เราแก้ไข NewLogger class ในไฟล์ logger.service.ts เป็นดังนี้
ไฟล์ logger.service.ts
import { Injectable } from '@angular/core'; import { BestStaffService } from './components/beststaff.service'; @Injectable() export class Logger { logs: string[] = []; // กำหนดตัวแปร array แบบ string log(message: string) { // ฟังก์ชั่น log() this.logs.push(message); // รับค่าข้อความและเพิ่มไปใน array console.log(message); // แสดงข้อความใน console } } @Injectable() export class NewLogger { constructor(private bestStaff:BestStaffService){ this.log(); } log() { // ฟังก์ชั่น log() let name = this.bestStaff.getBestStaff().name; console.log(name+" in NewLogger class"); } } @Injectable() export class EvenBetterLogger extends Logger { log(message: string) { console.log(message+" In EvenBetterLogger class"); super.log("ส่งข้อความไปในฟังก์ชั่น log() ของ Logger class"); } }
จะเห็นว่าเรามีการ import BestStaffService มาใช้งานในไฟล์ logger.service.ts
เพื่อนำ service เข้าไปใช้งานใน NewLogger class
ใน NewLogger class มีการสร้างตัวแปรอ้างอิงชื่อ bestStaff เป็นตัวแปรอ้างอิง BestStaffService
กำหนดเป็น private ใช้งานได้เฉพาะใน class นี้เท่านั้น นอกจากการสร้างตัวแปรใน constructor ฟังก์ชั่นแล้ว
เรามีการกำหนด ให้เรียกใช้คำสั่ง log() ในทันทีที่มีการใช้งาน NewLogger class
คำสั่ง log() จะทำการเรียกใช้งาน คำสั่ง getBestStaff() ผ่านตัวแปร bestStaff
โดยในตัวอย่างจะเป็นการไปดึงเฉพาะชื่อ ด้วยคำสั่ง getBestStaff().name แล้วเอามาเก็บไว้ในตัวแปร
ที่ชื่อ name
จากนั้นก็แสดงค่า name ต่อด้วย " in NewLogger class" ออกทาง console
ต่อไปเราจะไปดูที่ไฟล์ app.module.ts ซึ่งแน่นอนว่า เมื่อเรามีการเรียกใช้งาน BestStaffService เรา
ก็ต้องทำการขึ้นทะเบียน provider ในไฟล์นี้ก่อน
ไฟล์ app.module.ts
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { UserComponent } from './components/user.component'; import { StaffFormComponent } from './components/staff-form.component'; import { StaffListComponent } from './components/staff-list.component'; import { Logger,EvenBetterLogger,NewLogger } from './logger.service'; import { BestStaffService } from './components/beststaff.service'; @NgModule({ imports: [ BrowserModule, FormsModule ], declarations: [ AppComponent, UserComponent, StaffFormComponent, StaffListComponent ], providers:[ BestStaffService, { provide: Logger, useClass: NewLogger } ], bootstrap: [ AppComponent ] }) export class AppModule { }
สังเกตจะเห็นว่า NewLogger เป็นส่วนของ class provider ที่เรากำหนดไว้ใน Object ที่มี property
ชื่อว่า useClass
{ provide: Logger, useClass: NewLogger }
บรรทัดตามโค้ดด้านบนคือการกำหนดให้ใช้งานตัวแปร Logger อ้างอิงถึง class NewLogger
หรือก็คือการใช้ class provider อื่นแทน ซึ่งเราได้อธิบายแล้วที่ผ่านมา
และนี้คือรูปแบบการใช้งาน class provider ทีมีการนำเข้า service ที่ชื่อ BestStaffService
เรามาดูผลลัพธ์ จะเป็นดังนี้
จากรูปเราพบว่า มีการแสดงข้อมูลทาง console สองครั้ง ทั้งที่ควรแสดงครั้งเดียวจากคำสั่ง
this.log() ที่กำหนดให้ทำงานทันทีที่เรียกใช้งาน NewLogger class สาเหตุที่แสดงสองครั้ง
เพราะว่าหน้า App เรามีการแสดงรายชื่อ staff และในไฟล์ staff.service.ts มีการเรียกใช้คำสั่ง
log() ดังรูป
โดยคำสั่งนี้
this.logger.log('เรียกดูข้อมูล staff ...');
logger จะเป็นการตัวแปร ที่อ้างอิง NewLogger class ที่เรากำหนดใน provider ด้วยการใช้ useClass
เมื่อมีการใช้คำสั่ง logger.log() ก็เลยทำให้การแสดงข้อความออกทาง console อีกอันมาจากจุดนนี้เอง
การนำเข้า Service ให้เป็นแบบ Optional
ในไฟล์ logger.service.ts ส่วนของ NewLogger class ที่ผ่านเรามีการนำเข้า BestStaffService
เข้ามาใช้งาน แต่สมมุติว่า ถ้า service นี้ เราอยากกำหนดให้เป็น Optional หรือ สามารถเลือกที่จะนำเข้า
มาหรือไม่นำเข้าก็ได้ เราสามารถกำหนดได้โดยการใช้ข้อความ @Optional() โดยก่อนอื่นให้ import Optional เข้ามาก่อนเรียกใช้งาน
import { Optional } from '@angular/core';
จากนั้นกำหนด @Optional() เข้าไปใน constructor() ฟังก์ชั่นดังนี้
constructor(@Optional() private bestStaff:BestStaffService){ this.log(); } log() { // ฟังก์ชั่น log() if(this.bestStaff){ let name = this.bestStaff.getBestStaff().name; console.log(name+" in NewLogger class"); }else{ console.log("no staff in NewLogger class"); } }
การกำหนด @Optional() จะทำให้ตัวแปร bestStaff หรือ service class ที่จะนำเข้ามาเป็นค่า null
ก่อน แล้วถ้ามีการนำเข้า service ก็จะเปลี่ยนค่า service นั้นๆ แต่ถ้าไม่มีการนำเข้า ก็จะกลายเป็น null
และเราสามารถตรวจสอบค่าก่อนทำงานได้ ด้วยรูปแบบคำสั่ง
if(this.bestStaff){ // ถ้ามีการนำเข้า service และไม่ได้เป็น null ก็ให้ทำงานและเรียกใช้ service }
โค้ดไฟล์ logger.service.ts
import { Injectable } from '@angular/core'; import { Optional } from '@angular/core'; import { BestStaffService } from './components/beststaff.service'; @Injectable() export class Logger { logs: string[] = []; // กำหนดตัวแปร array แบบ string log(message: string) { // ฟังก์ชั่น log() this.logs.push(message); // รับค่าข้อความและเพิ่มไปใน array console.log(message); // แสดงข้อความใน console } } @Injectable() export class NewLogger { constructor(@Optional() private bestStaff:BestStaffService){ this.log(); } log() { // ฟังก์ชั่น log() if(this.bestStaff){ let name = this.bestStaff.getBestStaff().name; console.log(name+" in NewLogger class"); }else{ console.log("no staff in NewLogger class"); } } } @Injectable() export class EvenBetterLogger extends Logger { log(message: string) { console.log(message+" In EvenBetterLogger class"); super.log("ส่งข้อความไปในฟังก์ชั่น log() ของ Logger class"); } }
เราได้รู้จักกันไปพอสมควรกับขึ้นทะเบียน service class ใน provider เพื่อสร้าง
Injector provider สำหรับไปใช้งานใน App ตามส่วนต่างๆ การใช้งาน provider ค่อนข้าง
มีความสำคัญสำหรับ App ของเรามาก และเนื้อหาก็ค่อนข้างจะยากพร้อมกับซันซ้อนไปด้วย
ดังนี้ พยายามลองทำความเข้าใจกันดู และทบทวนหลายๆ ครั้ง ในตอนหน้า เราจะมาดู provider
แบบอื่นๆ ที่เหลือ เช่น Value provider Factory provider รวมทั้งการใช้งานการนำเข้า
DI ที่ไม่ใช้รูปแบบ class เพิ่มเติม รอติดตาม