Một phụ thuộc là một đối tượng mà một đối tượng khác phụ thuộc vào. Dependency Injection (hoặc inversion) về cơ bản là cung cấp các đối tượng mà một đối tượng cần, thay vì để nó tự xây dựng các đối tượng. Đây là một kỹ thuật hữu ích giúp kiểm tra dễ dàng hơn, vì nó cho phép bạn mô phỏng các phần phụ thuộc.
Ví dụ:nếu lớp A gọi một phương thức trên lớp B, lần lượt gọi một phương thức trên lớp C, điều đó có nghĩa là A phụ thuộc vào B và B phụ thuộc vào C. Sử dụng chèn phụ thuộc, chúng ta có thể chuyển một thể hiện của lớp C sang lớp B. và chuyển một thể hiện của B cho lớp A, thay vì để các lớp này tạo các thể hiện của B và C.
Trong ví dụ dưới đây, lớp Runner có sự phụ thuộc vào lớp Logger. Lưu ý rằng trong lớp Runner tạo một thể hiện của Logger trong phương thức khởi tạo. Có một số vấn đề với mã này.
-
Điều này liên kết lớp ghi nhật ký với Runner và chúng tôi không thể thay thế nó bằng các lớp khác mà không cần sửa đổi Runner.
-
Nếu Logger có bất kỳ phụ thuộc nào, thì Nhân viên phải định cấu hình chúng trước khi xác nhận Logger.
-
Kiểm tra khó hơn. Nếu Logger là một lớp sử dụng nhiều tài nguyên, chẳng hạn như truy cập mạng lưới hoặc hệ thống tệp, nó sẽ làm chậm quá trình kiểm tra. Chúng tôi không thể thay thế nó một cách dễ dàng.
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); } }
Sử dụng phương thức tiêm phụ thuộc, chúng tôi sửa đổi phương thức khởi tạo của Runner để chấp nhận một giao diện ILogger, thay vì một đối tượng cụ thể. Chúng tôi thay đổi lớp Logger để triển khai ILogger. Điều này cho phép chúng ta chuyển một thể hiện của lớp Logger đến phương thức khởi tạo của Runner. Lợi ích của việc này là trong quá trình thử nghiệm, chúng tôi có thể tạo một lớp TestLogger triển khai ILogger và chuyển nó cho phương thức khởi tạo của Runner.
Ví dụ
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); } }
Đầu ra
Message to be logged