[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"academy-blog-translations-none":3,"academy-blogs-th-1-1-all-js2go-ep47-dependency-injection-go-nodejs-all--*":4},{},{"data":5,"meta":69},[6],{"categoryId":7,"collectionId":8,"collectionName":9,"content":10,"createBy":11,"createDate":12,"created":13,"description":14,"expand":15,"group":60,"id":60,"image":61,"imageAlt":62,"imagePath":63,"keywordIds":64,"langId":56,"publishDate":65,"scheduleDate":12,"slug":66,"status":27,"title":62,"updateBy":11,"updated":67,"views":68},"hsa1afr8fcnd6qb","sclblg987654321","school_blog","\u003Cp>Dependency Injection (DI) คือเทคนิคสำคัญที่อยู่เบื้องหลังระบบระดับองค์กร ไม่ว่าจะเป็น API, Microservices, หรือ Enterprise Platform ช่วยให้โค้ด:\u003C\u002Fp>\u003Cul>\u003Cli>✔ Test ได้ง่ายกว่าเดิม 10 เท่า (Mock ได้ทุก dependency)\u003C\u002Fli>\u003Cli>✔ ลดความซับซ้อนและลด bug จาก global state\u003C\u002Fli>\u003Cli>✔ แยกความรับผิดชอบได้คมชัด (Separation of Concerns)\u003C\u002Fli>\u003Cli>✔ เปลี่ยนเทคโนโลยีได้โดยไม่กระทบระบบ เช่น DB driver \u002F external service\u003C\u002Fli>\u003Cli>✔ ควบคุม dependency graph ของระบบได้ถูกต้องและโปร่งใส\u003C\u002Fli>\u003C\u002Ful>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>DI = การ ส่ง dependency ที่ class\u002Fmodule\u002Fservice ต้องใช้เข้ามา แทนที่จะ new เอง ภายในฟังก์ชันหรือ service\u003C\u002Fp>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>⭐ 1) ทำไม Dependency Injection ทำให้ระบบ Testable มากขึ้น?\u003C\u002Fh2>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch3>❌ Anti-pattern: New dependency เองภายใน service\u003C\u002Fh3>\u003Cpre>\u003Ccode class=\"language-plaintext language-go\">type UserService struct {\n    repo *UserRepository\n}\n\nfunc NewUserService() *UserService {\n    return &amp;UserService{\n        repo: NewUserRepository(), \u002F\u002F ผูกตายตัว เปลี่ยนไม่ได้\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch3>🔥 ปัญหา\u003C\u002Fh3>\u003Cul>\u003Cli>เทสไม่ได้ → ต้องมี database จริง\u003C\u002Fli>\u003Cli>Mock ไม่ได้ → service ถูกล็อกกับ implementation เดียว\u003C\u002Fli>\u003Cli>ทำให้ระบบ coupling สูงมาก\u003C\u002Fli>\u003C\u002Ful>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch3>✔ Correct Pattern: Inject dependency จากภายนอก\u003C\u002Fh3>\u003Cpre>\u003Ccode class=\"language-plaintext language-go\">type UserService struct {\n    repo UserRepository\n}\n\nfunc NewUserService(repo UserRepository) *UserService {\n    return &amp;UserService{repo: repo}\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch3>🎉 ข้อดี\u003C\u002Fh3>\u003Cul>\u003Cli>Test ได้ง่ายโดยไม่ต้องใช้ DB จริง\u003C\u002Fli>\u003Cli>สลับ implementation ได้ เช่น pg → mongo → mock\u003C\u002Fli>\u003Cli>ลด coupling ทำให้ system maintain ง่ายขึ้น\u003C\u002Fli>\u003C\u002Ful>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>⭐ 2) Constructor-based DI ใน Go (มาตรฐานใน Production)\u003C\u002Fh2>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>Go ไม่มี DI container แบบอัตโนมัติ แต่ Go community นิยม Constructor Injection เพราะ:\u003C\u002Fp>\u003Cul>\u003Cli>debug ง่าย ไม่มีกลไกระดับ framework มาบัง\u003C\u002Fli>\u003Cli>track dependency graph ได้ง่าย\u003C\u002Fli>\u003Cli>เหมาะกับ Clean Architecture\u003C\u002Fli>\u003C\u002Ful>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch3>🎯 Interface = Dependency Contract\u003C\u002Fh3>\u003Cpre>\u003Ccode class=\"language-plaintext language-go\">type UserRepository interface {\n    FindByID(id string) (*User, error)\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch3>🎯 Implementation (Pg Repository)\u003C\u002Fh3>\u003Cpre>\u003Ccode class=\"language-plaintext language-go\">type PgUserRepository struct {\n    db *pgxpool.Pool\n}\n\nfunc (r *PgUserRepository) FindByID(id string) (*User, error) {\n    var u User\n    err := r.db.QueryRow(context.Background(),\n        \"SELECT id, name FROM users WHERE id=$1\", id).\n        Scan(&amp;u.ID, &amp;u.Name)\n\n    return &amp;u, err\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch3>🎯 Service (Inject repository)\u003C\u002Fh3>\u003Cpre>\u003Ccode class=\"language-plaintext language-go\">type UserService struct {\n    repo UserRepository\n}\n\nfunc NewUserService(repo UserRepository) *UserService {\n    return &amp;UserService{repo: repo}\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch3>🎯 Handler (Inject service)\u003C\u002Fh3>\u003Cpre>\u003Ccode class=\"language-plaintext language-go\">type UserHandler struct {\n    service *UserService\n}\n\nfunc NewUserHandler(s *UserService) *UserHandler {\n    return &amp;UserHandler{s}\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch3>🎯 Build Dependency Graph\u003C\u002Fh3>\u003Cpre>\u003Ccode class=\"language-plaintext language-go\">func BuildUserModule(db *pgxpool.Pool) *UserHandler {\n    repo := &amp;PgUserRepository{db: db}\n    service := NewUserService(repo)\n    handler := NewUserHandler(service)\n    return handler\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>นี่คือตัวอย่างของ Pure DI — ชัดเจน, trace ง่าย, ไม่มี magic\u003C\u002Fp>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>⭐ 3) DI Container ใน Node.js (Express, Nest, Awilix)\u003C\u002Fh2>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>Node.js community นิยมใช้ DI container เพื่อจัดการ dependency graph อัตโนมัติ เช่น:\u003C\u002Fp>\u003Cul>\u003Cli>Awilix (นิยมที่สุดใน Express)\u003C\u002Fli>\u003Cli>Tsyringe\u003C\u002Fli>\u003Cli>Inversify\u003C\u002Fli>\u003Cli>NestJS (มี DI built-in)\u003C\u002Fli>\u003C\u002Ful>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch3>🟧 ตัวอย่าง DI ด้วย Awilix (Express)\u003C\u002Fh3>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch4>ติดตั้งแพ็กเกจ\u003C\u002Fh4>\u003Cpre>\u003Ccode class=\"language-plaintext language-bash\">npm install awilix awilix-express\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch4>สร้าง Container\u003C\u002Fh4>\u003Cpre>\u003Ccode class=\"language-plaintext language-js\">import { createContainer, asClass } from \"awilix\";\n\nconst container = createContainer();\n\ncontainer.register({\n  userRepository: asClass(UserRepository),\n  userService: asClass(UserService),\n  userController: asClass(UserController)\n});\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch4>ใช้ใน Express\u003C\u002Fh4>\u003Cpre>\u003Ccode class=\"language-plaintext language-js\">import { scopePerRequest } from \"awilix-express\";\n\napp.use(scopePerRequest(container));\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>Awilix จะ inject dependency ให้โดยอัตโนมัติทุก request\u003C\u002Fp>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>⭐ 4) Mock Repository \u002F Service เพื่อ Test ได้ง่าย\u003C\u002Fh2>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch3>🟦 Go Mock Repository\u003C\u002Fh3>\u003Cpre>\u003Ccode class=\"language-plaintext language-go\">type MockUserRepo struct {\n    data map[string]User\n}\n\nfunc (m *MockUserRepo) FindByID(id string) (*User, error) {\n    if u, ok := m.data[id]; ok {\n        return &amp;u, nil\n    }\n    return nil, errors.New(\"not found\")\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch3>Test\u003C\u002Fh3>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cpre>\u003Ccode class=\"language-plaintext language-go\">repo := &amp;MockUserRepo{data: map[string]User{\n    \"1\": {ID: \"1\", Name: \"Ploy\"},\n}}\n\nservice := NewUserService(repo)\nuser, _ := service.GetUser(\"1\")\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>✔ ไม่ต้องใช้ DB จริง\u003Cbr>✔ test เร็วมาก\u003Cbr>✔ deterministic 100%\u003C\u002Fp>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch3>🟧 Node.js Mock Repository\u003C\u002Fh3>\u003Cpre>\u003Ccode class=\"language-plaintext language-js\">const mockRepo = {\n  findById: async (id) =&gt; ({ id, name: \"Ploy\" })\n};\n\nconst service = new UserService(mockRepo);\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>✔ เขียน test แบบ isolated ได้\u003Cbr>✔ ไม่แตะ database จริง\u003C\u002Fp>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>⭐ 5) ออกแบบ Dependency Graph อย่างถูกต้อง\u003C\u002Fh2>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>หลักการทองคำ:\u003C\u002Fp>\u003Cul>\u003Cli>Controller → Service → Repository → Database\u003C\u002Fli>\u003Cli>ห้าม Controller เรียก DB ตรง\u003C\u002Fli>\u003Cli>ห้าม Service new dependency เอง\u003C\u002Fli>\u003Cli>ห้าม Repository มี business logic\u003C\u002Fli>\u003Cli>ห้ามมี Circular Dependency\u003C\u002Fli>\u003C\u002Ful>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch3>ตัวอย่าง Dependency Graph (Clean Architecture)\u003C\u002Fh3>\u003Cpre>\u003Ccode class=\"language-plaintext\">HTTP Handler\n     ↓\nService Layer\n     ↓\nRepository Layer\n     ↓\nDatabase\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>ในระบบใหญ่จะเป็นแบบนี้:\u003C\u002Fp>\u003Cpre>\u003Ccode class=\"language-plaintext\">OrderAPI → OrderService → OrderRepo → PostgreSQL\n                 ↑\n            PaymentService → PaymentGateway\n                 ↑\n          InventoryService → InventoryRepo\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>DI ทำให้ graph ชัดเจนและจัดการง่าย\u003C\u002Fp>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>⭐ 6) Best Practices สำหรับ DI (Go + Node.js)\u003C\u002Fh2>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>✔ ใช้ Constructor Injection เป็นค่าเริ่มต้น\u003Cbr>✔ ทำ Interface\u002FAbstraction สำหรับทุก dependency\u003Cbr>✔ หลีกเลี่ยง global state\u003Cbr>✔ ใช้ DI container เฉพาะเมื่อระบบเริ่มใหญ่\u003Cbr>✔ Mock dependency เสมอสำหรับ unit test\u003Cbr>✔ แยก config ออกจาก logic\u003Cbr>✔ Dependency graph ต้องเป็นทิศทางเดียว (no cycles)\u003C\u002Fp>\u003Cp>&nbsp;\u003C\u002Fp>\u003Chr>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>📌 สรุป\u003C\u002Fh2>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>Dependency Injection ไม่ใช่ของหรูหรา แต่เป็นพื้นฐานที่ Back-end Developer ทุกคนต้องรู้!\u003C\u002Fp>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>DI ช่วยให้ระบบ:\u003C\u002Fp>\u003Cul>\u003Cli>🚀 ทดสอบง่าย\u003C\u002Fli>\u003Cli>🧱 ลด coupling\u003C\u002Fli>\u003Cli>🔄 เปลี่ยน implementation ได้สบาย\u003C\u002Fli>\u003Cli>🔍 debug ง่าย\u003C\u002Fli>\u003Cli>📦 ขยายระบบได้อย่างมั่นคงในระยะยาว\u003C\u002Fli>\u003C\u002Ful>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>Go → Constructor Injection คือมาตรฐานที่ดีที่สุด\u003Cbr>Node.js → Awilix หรือ NestJS ให้ DI พร้อมใช้งาน\u003C\u002Fp>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>DI + Dependency Graph ที่ดี\u003Cbr>= ระบบที่ “พร้อม scale ระดับ Production อย่างแท้จริง” 🎯\u003C\u002Fp>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>🔵 ตอนต่อไป: EP.48 Logging &amp; Monitoring for Production\u003C\u002Fh2>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>คุณจะได้เรียนรู้:\u003C\u002Fp>\u003Cul>\u003Cli>Structured Logging (Zap \u002F Zerolog \u002F Pino)\u003C\u002Fli>\u003Cli>Distributed Tracing (OpenTelemetry)\u003C\u002Fli>\u003Cli>Metrics (Prometheus + Grafana)\u003C\u002Fli>\u003Cli>Error Monitoring (Sentry)\u003C\u002Fli>\u003Cli>Correlation ID สำหรับ Microservices\u003C\u002Fli>\u003C\u002Ful>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cdiv class=\"raw-html-embed\">\u003Cdiv style=\"margin:0 0 6px 0; font-weight:700;\">อ่านบทความ Series อื่นๆ:\u003C\u002Fdiv>\n\u003Cul style=\"list-style:none; padding:0; margin:0; line-height:1.4;\">\n  \u003Cli style=\"margin:0;\">\u003Ca href=\"\u002Fblogs\u002Fcategories\u002FGolang\" title=\"Golang The Series\">Golang The Series\u003C\u002Fa>\u003C\u002Fli>\n  \u003Cli style=\"margin:0;\">\u003Ca href=\"\u002Fblogs\u002Fcategories\u002FJS2GO\" title=\"JS2GO\">JS2GO\u003C\u002Fa>\u003C\u002Fli>\n  \u003Cli style=\"margin:0;\">\u003Ca href=\"\u002Fblogs\u002Fcategories\u002FTailwind%20CSS\" title=\"10 Ep ที่จะให้คุณเป็นมือโปร Tailwind CSS ในชั่วข้ามคืน\">10 Ep ที่จะให้คุณเป็นมือโปร Tailwind CSS ในชั่วข้ามคืน\u003C\u002Fa>\u003C\u002Fli>\n\u003C\u002Ful>\u003C\u002Fdiv>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cdiv class=\"raw-html-embed\">\n  \u003Cp style=\"margin:0 0 6px 0;\">\u003Cstrong>Follow Us:\u003C\u002Fstrong>\u003C\u002Fp>\n  \u003Cul style=\"list-style:none; padding:0; margin:0; line-height: 0.4;\">\n    \u003Cli style=\"display:flex; align-items:center; gap:6px; margin:0;\">\n      \n      \u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"#1877F2\" aria-hidden=\"true\">\n        \u003Cpath d=\"M22 12.07C22 6.48 17.52 2 11.93 2S2 6.48 2 12.07c0 5 3.66 9.14 8.44 9.93v-7.02H7.9v-2.91h2.54V9.41c0-2.5 1.49-3.88 3.77-3.88 1.09 0 2.24.2 2.24.2v2.46h-1.26c-1.24 0-1.63.77-1.63 1.56v1.87h2.78l-.44 2.91h-2.34V22c4.78-.79 8.44-4.93 8.44-9.93Z\">\u003C\u002Fpath>\n      \u003C\u002Fsvg>\n      \u003Ca href=\"https:\u002F\u002Fwww.facebook.com\u002Fsuperdev.academy.th\" target=\"_blank\" rel=\"nofollow noopener\" title=\"Follow Superdev Academy on Facebook\">Facebook: Superdev Academy\u003C\u002Fa>\n    \u003C\u002Fli>\n\n    \u003Cli style=\"display:flex; align-items:center; gap:6px; margin:0;\">\n      \n      \u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"#FF0000\" aria-hidden=\"true\">\n        \u003Cpath d=\"M23.5 6.2a3 3 0 0 0-2.1-2.1C19.5 3.5 12 3.5 12 3.5s-7.5 0-9.4.6A3 3 0 0 0 .5 6.2 31.5 31.5 0 0 0 0 12a31.5 31.5 0 0 0 .5 5.8 3 3 0 0 0 2.1 2.1c1.9.6 9.4.6 9.4.6s7.5 0 9.4-.6a3 3 0 0 0 2.1-2.1A31.5 31.5 0 0 0 24 12a31.5 31.5 0 0 0-.5-5.8ZM9.75 15.02V8.98L15.5 12l-5.75 3.02Z\">\u003C\u002Fpath>\n      \u003C\u002Fsvg>\n      \u003Ca href=\"https:\u002F\u002Fwww.youtube.com\u002F@SuperdevAcademy\" target=\"_blank\" rel=\"nofollow noopener\" title=\"Watch on YouTube\">YouTube: Superdev Academy\u003C\u002Fa>\n    \u003C\u002Fli>\n\n    \u003Cli style=\"display:flex; align-items:center; gap:6px; margin:0;\">\n      \n      \u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"#E4405F\" aria-hidden=\"true\">\n        \u003Cpath d=\"M7 2h10a5 5 0 0 1 5 5v10a5 5 0 0 1-5 5H7a5 5 0 0 1-5-5V7a5 5 0 0 1 5-5Zm10 2H7a3 3 0 0 0-3 3v10a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V7a3 3 0 0 0-3-3Zm-5 3.5A5.5 5.5 0 1 1 6.5 13 5.5 5.5 0 0 1 12 7.5Zm0 2A3.5 3.5 0 1 0 15.5 13 3.5 3.5 0 0 0 12 9.5Zm5.75-2.75a1.25 1.25 0 1 1-1.25 1.25 1.25 1.25 0 0 1 1.25-1.25Z\">\u003C\u002Fpath>\n      \u003C\u002Fsvg>\n      \u003Ca href=\"https:\u002F\u002Fwww.instagram.com\u002Fsuperdevacademy\u002F?hl=en target=\" _blank\"=\"\" rel=\"nofollow noopener\" title=\"See behind-the-scenes on Instagram\">Instagram: Superdev Academy\u003C\u002Fa>\n    \u003C\u002Fli>\n\n    \u003Cli style=\"display:flex; align-items:center; gap:6px; margin:0;\">\n      \n      \u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"#000000\" aria-hidden=\"true\">\n        \u003Cpath d=\"M21 8.12a6.86 6.86 0 0 1-4.8-2V16a6 6 0 1 1-6-6 5.9 5.9 0 0 1 1.63.23V8.05a9.08 9.08 0 0 1-1.63-.15V4.5a6.86 6.86 0 0 0 4.8 2.05V6.5a6.86 6.86 0 0 0 4.8 1.62ZM9.2 12.5A3.5 3.5 0 1 0 12.7 16V9.94a6 6 0 0 1-1.63-.27v3.95a3.5 3.5 0 0 1-1.87 3.17 3.5 3.5 0 0 1-4.78-3.23 3.5 3.5 0 0 1 4.78-3.06Z\">\u003C\u002Fpath>\n      \u003C\u002Fsvg>\n      \u003Ca href=\"https:\u002F\u002Fwww.tiktok.com\u002F@superdevacademy\" target=\"_blank\" rel=\"nofollow noopener\" title=\"Watch short tips on TikTok\">TikTok: @superdevacademy\u003C\u002Fa>\n    \u003C\u002Fli>\n\n    \u003Cli style=\"display:flex; align-items:center; gap:6px; margin:0;\">\n      \n      \u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"#111827\" aria-hidden=\"true\">\n        \u003Cpath d=\"M12 2a10 10 0 1 0 10 10A10.01 10.01 0 0 0 12 2Zm6.93 6h-3.26a15.6 15.6 0 0 0-1.39-3.62A8.03 8.03 0 0 1 18.93 8ZM12 4c.73.93 1.7 2.74 2.2 4H9.8C10.3 6.74 11.27 4.93 12 4ZM8.72 4.38A15.6 15.6 0 0 0 7.32 8H4.07a8.03 8.03 0 0 1 4.65-3.62ZM4.07 16h3.25a15.6 15.6 0 0 0 1.4 3.62A8.03 8.03 0 0 1 4.07 16ZM12 20c-.73-.93-1.7-2.74-2.2-4h4.4C13.7 17.26 12.73 19.07 12 20Zm3.28-.38A15.6 15.6 0 0 0 16.68 16h3.25a8.03 8.03 0 0 1-4.65 3.62ZM20 14h-3.54a13.8 13.8 0 0 1-.26-4H20a7.98 7.98 0 0 1 0 4Zm-12.2 0H4a7.98 7.98 0 0 1 0-4h3.54a13.8 13.8 0 0 1-.26 4Zm2 .5h4.4a17.8 17.8 0 0 1-.72-4.5c0-1.58.25-3.1.72-4.5H9.8a17.8 17.8 0 0 1 .72 4.5c0 1.58-.25 3.1-.72 4.5Z\">\u003C\u002Fpath>\n      \u003C\u002Fsvg>\n      \u003Ca href=\"https:\u002F\u002Fwww.superdevacademy.com\u002F\" target=\"_blank\" rel=\"noopener\" title=\"Visit the official website of Superdev Academy\">Official Website: Superdev Academy.com\u003C\u002Fa>\n    \u003C\u002Fli>\n  \u003C\u002Ful>\n\u003C\u002Fdiv>\u003Cp>&nbsp;\u003C\u002Fp>","r8v4zgsahjuwpeb","","2026-03-04 08:45:02.070Z","DI คือเทคนิคสำคัญที่ช่วยให้ระบบทดสอบง่าย ลดการผูกติดกันของโค้ด และปรับเปลี่ยน implementation ได้โดยไม่กระทบส่วนอื่น บทความนี้อธิบายแนวคิด DI พร้อมโค้ดตัวอย่างใน Go (pgx\u002FGORM) และ Node.js รวมถึงวิธีทำให้ระบบพร้อมสำหรับ Production จริง",{"categoryId":16,"keywordIds":29,"langId":51},{"blogIds":17,"collectionId":18,"collectionName":19,"createBy":12,"created":20,"id":7,"image":21,"imageAlt":12,"imagePath":22,"label":23,"name":24,"priority":25,"publishDate":26,"scheduleDate":12,"status":27,"updateBy":12,"updated":28},[],"sclcatblg987654321","school_category_blog","2026-03-04 08:24:37.986Z","js2_go_2_11zon_y6paxmuz32.webp","https:\u002F\u002Ftwsme-r2.tumwebsme.com\u002Fsclcatblg987654321\u002Fhsa1afr8fcnd6qb\u002Fjs2_go_2_11zon_y6paxmuz32.webp",{"en":24,"th":24},"JS2GO",10,"2025-08-11 03:41:08.820Z","Publish","2026-03-17 06:07:58.076Z",[30,37,41,46],{"collectionId":31,"collectionName":32,"createBy":12,"created":33,"id":34,"publishDate":35,"scheduleDate":12,"status":27,"title":36,"updateBy":12,"updated":33},"sclkey987654321","school_keyword","2026-03-04 08:45:01.083Z","anx8rod7y41shjl","2025-12-17 02:26:07.719Z","Clean Architecture",{"collectionId":31,"collectionName":32,"createBy":12,"created":38,"id":39,"publishDate":35,"scheduleDate":12,"status":27,"title":40,"updateBy":12,"updated":38},"2026-03-04 08:45:01.460Z","bbwe2jz83qa1d1j","Dependency Injection",{"collectionId":31,"collectionName":32,"createBy":12,"created":42,"id":43,"publishDate":44,"scheduleDate":12,"status":27,"title":45,"updateBy":12,"updated":42},"2026-03-04 08:24:40.405Z","05u3tysava2z6ga","2025-08-18 13:42:48.927Z","Node.js",{"collectionId":31,"collectionName":32,"createBy":12,"created":47,"id":48,"publishDate":49,"scheduleDate":12,"status":27,"title":50,"updateBy":12,"updated":47},"2026-03-04 08:20:11.547Z","ey3puyme01a9bsw","2026-01-28 00:54:28.566Z","Go",{"code":52,"collectionId":53,"collectionName":54,"createAt":55,"id":56,"is_default":57,"language":58,"updateAt":59},"th","pbc_1989393366","locale","2026-01-22 10:59:55.832Z","s8wri3bt4vgg2ji",true,"Thai","2026-03-18 22:06:10.043Z","89duht4c5ae6qrn","cover_image_js2_go_ep_47_dependency_injection_in_go_and_node_hehykg0srq.geSystemsNeedDI.webp","JS2GO EP.47 Dependency Injection ใน Go และ Node.js: ทำไมระบบใหญ่ต้องมี DI?","https:\u002F\u002Ftwsme-r2.tumwebsme.com\u002Fsclblg987654321\u002F89duht4c5ae6qrn\u002Fcover_image_js2_go_ep_47_dependency_injection_in_go_and_node_hehykg0srq.geSystemsNeedDI.webp",[34,39,43,48],"2025-12-17 02:25:59.478Z","js2go-ep47-dependency-injection-go-nodejs","2026-03-04 08:45:02.399Z",247,{"pagination":70},{"page":71,"pageSize":71,"pageCount":71,"total":71},1]