Con Contortor tiêm có lợi thế là nó làm cho sự phụ thuộc rõ ràng và buộc khách hàng phải cung cấp một thể hiện. Nó cũng có thể đảm bảo rằng máy khách không thể thay đổi thể hiện sau này. Một nhược điểm (có thể) là bạn phải thêm một tham số cho hàm tạo của mình.
Setter Injection có lợi thế là nó không yêu cầu thêm tham số vào hàm tạo. Nó cũng không yêu cầu khách hàng thiết lập thể hiện. Điều này rất hữu ích cho các phụ thuộc tùy chọn. Điều này cũng có thể hữu ích nếu bạn muốn lớp tạo, ví dụ, một kho lưu trữ dữ liệu thực theo mặc định, và sau đó trong một thử nghiệm, bạn có thể sử dụng setter để thay thế nó bằng một thể hiện kiểm tra.
Giao diện tiêm , theo như tôi có thể nói, không khác nhiều so với tiêm setter. Trong cả hai trường hợp, bạn (tùy chọn) thiết lập một phụ thuộc có thể được thay đổi sau này.
Cuối cùng nó là một vấn đề ưu tiên và có hoặc không phụ thuộc là cần thiết . Cá nhân, tôi sử dụng tiêm constructor gần như độc quyền. Tôi thích điều đó làm cho các phụ thuộc của một lớp rõ ràng bằng cách buộc máy khách cung cấp một thể hiện trong hàm tạo. Tôi cũng thích rằng khách hàng không thể thay đổi trường hợp sau khi thực tế.
Thông thường, lý do duy nhất của tôi để thông qua hai triển khai riêng biệt là để thử nghiệm. Trong sản xuất, tôi có thể vượt qua trong một DataRepository
, nhưng trong thử nghiệm, tôi sẽ vượt qua trong một FakeDataRepository
. Trong trường hợp này, tôi thường sẽ cung cấp hai hàm tạo: một không có tham số và một hàm chấp nhận a IDataRepository
. Sau đó, trong hàm tạo không có tham số, tôi sẽ xâu chuỗi một cuộc gọi đến hàm tạo thứ hai và chuyển vào a new DataRepository()
.
Đây là một ví dụ trong C #:
public class Foo
{
private readonly IDataRepository dataRepository;
public Foo() : this(new DataRepository())
{
}
public Foo(IDataRespository dataRepository)
{
this.dataRepository = dataRepository;
}
}
Điều này được gọi là tiêm phụ thuộc của người nghèo. Tôi thích nó bởi vì trong mã khách hàng sản xuất, tôi không cần phải lặp lại chính mình bằng cách có một vài câu lệnh lặp đi lặp lại trông giống như
var foo = new Foo(new DataRepository());
Tuy nhiên, tôi vẫn có thể vượt qua trong một triển khai thay thế để thử nghiệm. Tôi nhận ra rằng với DI của Poor Man, tôi đang giải mã sự phụ thuộc của mình, nhưng tôi chấp nhận được vì tôi chủ yếu sử dụng DI để thử nghiệm.