บทความชุด .NET 6 แบบจับมือทำ — #9: Core Project
Core Project
ในส่วนของ Project นี้เราจะทำหน้าที่กำหนดในเรื่องของมาตราฐานในการพัฒนา Backing Service (เช่นการต่อ Database, Logging, Email) ผ่าน Interface (ต่อไปนี้จะขอเรียกว่า Infrastructure Interface) ส่วนการนำ Interface ไปพัฒนาต่อนั้นจะเป็นหน้าที่ของทาง Infra Project นะครับ
ในบทความนี้เราจะใช้ Repository Pattern เพื่อช่วยแยกความสัมพันธ์ระหว่าง Business Domain Model (อยู่ใน Domain Project) และ Data Access Layer (อยู่ใน Infra Project) ซึ่งจะทำให้เราทำ Mock Data เพื่อเขียน Unit Test ได้สะดวกขึ้นครับ
Repository Pattern
ทำการกำหนดมาตราฐานของฟังชั่นที่ควรจะมีใน Base Repository Interface และ ทำการพัฒนาที่ Base Repository Class เพื่อที่ Repository อื่นจะได้นำไปใช้ต่อ
ต้องมี Repository Interface แยกตามแต่ละ Business Domain Model เพื่อรองรับ Query ที่แตกต่างกันไป เช่น บาง Repository อาจจะมีแค่การดึงข้อมูลง่ายๆจาก 1 Business Domain Model หรือบาง Repository อาจจะมีแค่การดึงข้อมูลจากหลายๆ Business Domain Model
Repository Interface อื่นๆสามารถลดเวลาการ Implement ตาม Base Repository Interfaceได้ด้วยการ สืบทอด Base Repository Class
พัฒนา Infrastructure Interface — Repository Pattern
อันดับแรกให้สร้าง Folder Interface/Infra/Database เพื่อเก็บ Interface ที่เกี่ยวข้องกับการสร้าง Repository นะครับ ส่วนการพัฒนา Interface เราจะไปทำที่ Infra Project กันครับผม
เสร็จแล้วให้สร้าง Files ดังนี้นะครับ
_IBaseRepository.cs
=> ใช้เพื่อเก็บโครงสร้างพื้นฐานที่ทุกๆ Repository ควรจะมีครับIProvinceRepository.cs
=> เน้นการจัดการข้อมูลที่เกี่ยวกับ Domain Model Province จาก Domain ProjectIPointOfInterestRepository.cs
=> เน้นการจัดการข้อมูลที่เกี่ยวกับ Domain Model PointOfInterest จาก Domain Project
ถ้าเรามี Business Domain ใหม่ๆ เราก็สามารถเพิ่ม Repository Interface เข้ามาอีกได้นะครับ
ให้ทำการ Copy Code จากลิ้งข้างล่างนี้นะครับ
พัฒนา Infrastructure Interface — Email
อันดับแรกให้สร้าง Folder Interface/Infra/Email เพื่อเก็บ Interface ที่เกี่ยวข้องกับมาตราฐานการพัฒนา Email Interface กันนะครับ
เสร็จแล้วให้สร้าง File ชื่อ IEmailProvider.cs และ Copy Code จากที่นี้ได้เลยครับ
พัฒนา Business Service Interface-Token Service
บริการนี้จะทำหน้าที่ส่ง Token ไปทาง Email นะครับ
ให้เราสร้าง Folder ชื่อ Interfaces/Services และสร้าง File ชื่อ ITokenService.cs พร้อม Copy Code จากลิ้งข้างล่างนี้นะครับ
พัฒนา Business Service-Token Service
ถ้าเป็นการเขียน Code สมัยก่อน เราอาจจะคุ้นชินกับการที่อ้างอิงพวก Concrete Implementation เช่นระบุ Class ที่ Implement ทั้ง Configuration และ Code ที่ต่อไปยัง Email Provider พร้อมแล้วนะครับ
ในบทความนี้เราจะใช้ DI มาช่วยทำให้เป็นการอ้างอิงถึง Abstraction เช่น Interface แทนนะครับโดยจะทดลองนำ Infrastructure Interface — Email มาเรียกใช้ในบริการของการส่ง Token ไปทาง Email นะครับ ลุย !!!
ให้เพิ่ม Folder ชื่อ Services และสร้าง File ชื่อ TokenService.cs และ Copy Code ตามลิ้งนี้นะครับ
พัฒนา Business Service Interface— ProvinceService
ในขั้นตอนนี้ผมอยากสาธิตการเขียน CRUD ด้วยวิธีการคุยกันกับ Repository ผ่าน Interface แทนที่จะเป็นการคุยผ่าน Concrete Class — DAL ต่างๆแบบในอดีตนะครับ
เพื่อสื่อให้เห็นว่าเราสามารถแบ่งแยก Infra ต่างๆออกไปพัฒนาในภายหลังได้ ทำให้ระบบยืดหยุ่น สลับไปสลับมาระหว่าง Infra ที่จะนำมาใช้ได้ครับ เช่นอาจจะเคยต่อ MSSQL เราก็สามารถเปลี่ยนเป็น MySQL, PostgreSQL รวมไปถึง MongoDB ได้ในอนาคตครับ โดยไม่กระทบ Code ใน Core Project เลย เพราะ
ให้เราสร้าง File ชื่อ ProvinceService.cs และ Copy Code ตามลิ้งนี้นะครับ
ขออธิบายบางส่วนของ Code นะครับ
ในการ Create Province ขึ้นมาใหม่นั้น เราจะทำการตรวจสอบก่อนว่ามีชื่อที่ซ้ำในระบบหรือไม่ โดยการเรียกใช้ฟังชั่นจาก Base Repository ชื่อ DoesExists()
ซึ่งถ้าถามว่า ฟังชั่น DoesExists() ทำงานยังไง เอาจริงๆเราก็ยังไม่รู้เลยครับ แต่เราตั้งเป็นมาตราฐานไว้ใน Interface ว่าฟังชั่นนี้ให้ทำหน้าที่ตรวจสอบว่ามี Province ที่ถูกสร้างด้วย Name ที่ระบุหรือยังในฐานข้อมูลนะครับ ส่วนการพัฒนา Interface นี้ค่อยไปดูใน Infra Project ในหัวข้อถัดไปนะครับ (มันจะขัดๆกับคนที่เคยเขียนโปรแกรมสมัยก่อนที่เราไปสร้างการต่อ DB ให้เสร็จก่อนแล้วค่อยเอามาเรียกใช้ที่นี้นะครับ เราค่อยๆเรียนรู้กันไปนะครับ สู้ๆ)
หลังจากนั้นเราทำการแปลง Input Model มาเป็น Domain Model แล้วก็ส่งเข้าไปสร้างใน AddAsync() ต่อไปครับ
Key หลักของ Core Model คือการที่เรารับ Input มาและทำการแปลงเป็น Domain Model เพื่อ แก้ไขข้อมูลในระบบ เสร็จแล้วทำการแปลง Domain Model ให้หลายเป็น Output ตามแต่ละ Use Case ที่ API Project ต้องการนะครับ เราจะไม่ Expose Domain Model ออกไปที่ API Project ตรงๆเพื่อปกป้องข้อมูลในฐานข้อมูลของเราครับ
ลุยกันครับบบบ
- #0: เกริ่นนำ
- #1: ติดตั้งโปรแกรม
- #2: รวม Cheat Sheet
- #3: Empty Solution in GitHub
- #4: พัฒนาโครงสร้างของ Source Code
- #5: VS Code Debugging
- #6: Configuration
- #7: Dependency Injection & Service Lifetime
- #8: Domain Project
- #9: Core Project
- #10: Infra Project
- #11: API Project
- #12: Unit Testing
- #13: Logging and Monitoring
- #14:เพิ่มความปลอดภัยด้วย OAuth2 & OpenID Connect
- #15: Background Process & Scheduler
- #16: Health Checks
- #17: The Twelve-Factor App
- #18: Deployment — Docker
- #19: Deployment — Azure App Service
- #20: Deployment — Azure Container Apps