nattapong99 / book

0 stars 0 forks source link

Part 4: Symfony Service Container: Using a Builder to create Services #8

Open nattapong99 opened 6 years ago

nattapong99 commented 6 years ago

Symfony Service Container: Using a Builder to create Services

ในบทความก่อนหน้านี้ของ Dependency Injection คุณได้เรียนรู้การใช้คลาส sfServiceContainer เพื่อทำให้ interface ของ service container น่าสนใจมากขึ้น โดยในบทความนี้ เราจะเรียนรู้การใช้คลาส sfServiceContainerBuilder ที่ใช้จัดการ service

The Service Container Interface

ทุกคลาส service container ใช้ sfServiceContainerInterface

01

การกำหนด services ทำได้โดยการลงทะเบียนข้อกำหนดของ service โดยแต่ละข้อกำหนดของ service จะอธิบายถึงแต่ละ service จากคลาสที่จะใช้เพื่อส่งอาร์กิวเมนต์ที่ผ่าน constructor และพวงการกำหนดค่าอื่น ๆ ของ properties (ดู sfServiceDefinition ด้านล่าง)

จากตัวอย่าง Zend_Mail สามารถเขียนใหม่และทำให้มีความยืดหยุ่นโดยใช้คลาส builder

02

การสร้าง service เสร็จสิ้นโดยการเรียกเมธอด register() ซึ่งเราได้ส่งชื่อ service และชื่อคลาสไป ทำให้ได้ sfServiceDefinition instance กลับมา

การระบุ service จะถูกแสดงขึ้นภายในโดย object ของคลาส sfServiceDefinition นอกจากนี้ยัง
สามารถสร้างและลงทะเบียนมันได้โดยตรงโดยใช้คอนเทนเนอร์เซอร์วิส setServiceDefinition () method

ในตัวอย่างข้างบน เราได้ใช้สิ่งเหล่านี้

การอ้างอิง service เสร็จสิ้นด้วยการใช้ sfServiceReference instance โดยนี่คือ special object แบบไดนามิกซึ่งถูกแทนที่ด้วย service จริง ๆ เมื่อการอ้างอิง service ถูกสร้างขึ้น

ในระหว่างขั้นตอนการลงทะเบียน service ยังไม่ได้ถูกสร้างจริง ๆ มันยังเป็นเพียงแค่การให้คำจำกัดความกับ service เท่านั้น service จะถูกสร้างขึ้นจริง ๆ ก็ต่อเมื่อคุณทำงานกับมันจริง ๆ นั้นหมายความว่าคุณสามารถลงทะเบียน service ในคำสั่งต่าง ๆ ได้โดยไม่ต้องคำนึงถึง dependency ของมัน ซึ่งก็หมายความอีกว่าคุณสามารถแทนที่ service ที่มีอยู่แล้วและลงทะเบียนมันอีกครั้งในชื่อเดิมได้ นี่เป็นอีกหนึ่งวิธีง่าย ๆ ในการแทนที่ service เพื่อการทดสอบ

The sfServiceDefinition Class

service นั้นมีหลาย property ที่เปลี่ยนแปลงวิธีในการสร้างและกำหนดค่า

  • setConstructor() กำหนด static method เพื่อใช้เมื่อ service ได้ถูกสร้างขึ้น, แทนที่ของการสร้าง construct ทั่วไป (มีประโยชน์สำหรับ factory)
  • setClass() กำหนดคลาส service
  • setArgument() กำหนดอาร์กิวเมนต์ที่ส่งไปยัง constructor (เป็นคำสั่งที่สำคัญ)
  • addArgument() เพิ่มอาร์กิวเมนต์สำหรับ constructor
  • setMethodCalls() กำหนดเมธอด service เพื่อเรียกใช้หลังจากที่ service ได้สร้างขึ้น โดยเมธอดเหล่านี้มีการเรียกใช้ตั้งแต่การลงทะเบียน
  • addMethodCall() เพิ่มเมธอด service ที่จะใช้เรียกหลังจากที่ service ได้ถูกสร้างขึ้น โดยสามารถเพิ่มการเรียกไปยังเมธอดเดิมได้หลายครั้งหากต้องการ
  • setFile() ตั้งค่าไฟล์ที่จะรวมก่อนที่จะสร้าง service (มีประโยชน์ถ้าคลาส service ถ้าไม่ใช้ autoloaded)
  • setShared() เช็คว่ามี service นี้ซ้ำใน container หรือไม่ (ค่าเริ่มต้นเป็น true)
  • setConfigurator() ตั้งค่า PHP callable เพื่อเรียกใช้หลังจากที่มีการกำหนดค่า service แล้ว

เนื่องจากคลาส sfServiceContainerBuilder ใช้อินเทอร์เฟซ sfServiceContainerInterface ทำให้การใช้ service container ไม่จำเป็นต้องมีการเปลี่ยนแปลง

03

sfServiceContainerBuilder สามารถอธิบาย object instantiation และการกำหนดค่าได้ เราได้แสดงให้เห็นการใช้แล้วกับคลาส Zend_Mail และนี่คืออีกตัวอย่างหนึ่งที่ใช้คลาส sfUser จาก Symfony

04

ในตัวอย่าง Symfony แม้ว่า object ที่จัดเก็บจะใช้อาร์เรย์ของอ็อพชันเป็นอาร์กิวเมนต์ 
เราสามารถส่งผ่าน string placeholder (addArgument ('%storage.options%')) 
container จะฉลาดพอที่จะส่งอาร์เรย์ได้สำหรับค่าของ placeholder

การใช้ PHP code ในการกำหนด service ทำได้ง่ายและมีประสิทธิภาพ มันช่วยให้คุณมีเครื่องมือเพื่อใช้สร้าง container ของคุณ โดยที่ไม่มี duplicate code เกิดขึ้น, การสร้าง abstract object, การกำหนดค่า ในบทความหน้าเราจะได้รู้วิธีการระบุ services ในรูปแบบ XML และ YAML

source