การพึ่งพาเป็นวัตถุที่วัตถุอื่นขึ้นอยู่กับ การพึ่งพาการฉีด (หรือการผกผัน) นั้นเป็นการจัดหาวัตถุที่วัตถุต้องการโดยพื้นฐาน แทนที่จะให้วัตถุนั้นสร้างเอง เป็นเทคนิคที่มีประโยชน์ที่ช่วยให้การทดสอบง่ายขึ้น เนื่องจากช่วยให้คุณจำลองการขึ้นต่อกันได้
ตัวอย่างเช่น ถ้าคลาส A เรียกใช้เมธอดบนคลาส B ซึ่งในทางกลับกันเรียกเมธอดในคลาส C นั่นหมายความว่า A ขึ้นอยู่กับ B และ B ขึ้นอยู่กับ C การใช้การพึ่งพาการฉีด เราสามารถส่งอินสแตนซ์ของคลาส C ไปยังคลาส B ได้ และส่งผ่านอินสแตนซ์ของ B ไปยังคลาส A แทนที่จะให้คลาสเหล่านี้สร้างอินสแตนซ์ของ B และ C
ในตัวอย่างด้านล่าง class Runner มีการพึ่งพาคลาส Logger ขอให้สังเกตว่าในคลาส Runner สร้างอินสแตนซ์ของ Logger ในตัวสร้าง รหัสนี้มีปัญหาเล็กน้อย
-
สิ่งนี้เชื่อมโยงคลาส logger กับ Runner และเราไม่สามารถแทนที่ด้วยคลาสอื่นโดยไม่ต้องแก้ไข Runner
-
หาก Logger มีการพึ่งพาใด ๆ ผู้ปฏิบัติงานจะต้องกำหนดค่าก่อนที่จะสร้าง Logger
-
การทดสอบยากขึ้น หาก Logger เป็นคลาสที่ใช้ทรัพยากรมาก เช่น การเข้าถึงเครือข่ายหรือระบบไฟล์ จะทำให้การทดสอบช้าลง เราไม่สามารถเปลี่ยนมันได้ง่ายๆ
using System; class Program{ static void Main(string[] args){ var runner = new Runner(); runner.Run(); } } class Runner{ private Logger _logger; public Runner(){ _logger = new Logger(); } public void Run(){ // Do some work _logger.Log("Message to be logged"); } } class Logger{ public void Log(string message){ Console.WriteLine(message); } }
การใช้การพึ่งพาการฉีด เราปรับเปลี่ยนคอนสตรัคเตอร์ของ Runner ให้ยอมรับอินเทอร์เฟซ ILogger แทนที่จะเป็นวัตถุที่เป็นรูปธรรม เราเปลี่ยนคลาส Logger เพื่อใช้งาน ILogger สิ่งนี้ทำให้เราสามารถส่งผ่านอินสแตนซ์ของคลาส Logger ไปยังคอนสตรัคเตอร์ของ Runner ประโยชน์ของสิ่งนี้คือในระหว่างการทดสอบ เราสามารถสร้างคลาส TestLogger ที่ใช้ ILogger และส่งผ่านไปยัง Constructor ของ Runner
ตัวอย่าง
using System; class Program{ static void Main(string[] args){ var logger = new Logger(); var runner = new Runner(logger); runner.Run(); } } class Runner{ private ILogger _logger; public Runner(ILogger logger){ _logger = logger; } public void Run(){ // Do some work _logger.Log("Message to be logged"); } } interface ILogger{ void Log(string message); } class Logger : ILogger{ public void Log(string message){ Console.WriteLine(message); } }
ผลลัพธ์
Message to be logged