Phụ thuộc tiêm và Singleton. Có phải họ là hai khái niệm hoàn toàn khác nhau?


17

Tôi đã được nghe về việc sử dụng thuốc tiêm phụ thuộc vào Singleton cho đồng nghiệp của tôi. Tôi vẫn không thể nhận ra nếu đó là hai mẫu trực giao có thể thay thế bằng nhau? Hay DI là một phương pháp để làm cho mẫu Singleton có thể kiểm tra được?

Xin hãy xem đoạn mã sau đây.

    IMathFace obj = Singleton.Instance;

    SingletonConsumer singConsumer = new SingletonConsumer(obj);

    singConsumer.ConsumerAdd(10,20);

Việc SingletonConsumerchấp nhận một tham số của loại IMathFace. Thay vì truy cập vào lớp singleton trong nội bộ, SingletonConsumersẽ nhận được cá thể singleton được người gọi thông qua. Đây có phải là một ví dụ tốt về việc tiêu thụ lớp singleton thông qua tiêm phụ thuộc?


Bạn có thể vui lòng cho tôi biết làm thế nào DI có thể thay thế singleton?

7
Singleton là một mẫu thiết kế. DI / IoC là một kỹ thuật.
Dave

2
DI không thể thay thế Singleton nhiều hơn một quả chuối có thể thay thế bộ chế hòa khí. Chúng là những khái niệm hoàn toàn khác nhau.
Dave

vì vậy ví dụ của tôi là hợp lệ.

1
Có, nhưng có thể phải trả chi phí đóng gói (điều này cũng đúng với người không độc thân) xem: stackoverflow.com/questions/1005473/

Câu trả lời:


17

Tôi nghĩ rằng anh ta có nghĩa là bạn nên sử dụng nội xạ phụ thuộc để tiêm một phiên bản dịch vụ duy nhất, thay vì sử dụng triển khai Singleton cổ điển với một bộ truy cập tĩnh MySingleton.Instance.

public class MySingleton
{
    public static MySingleton Instance{get{...}};
}

Với việc triển khai singleton cổ điển, tất cả mã của bạn phụ thuộc vào dịch vụ đó là một singleton. Về cơ bản, bạn hardcode giả định tiêu thụ mã bất cứ khi nào bạn sử dụng MySingleton.Instance.

Mặt khác với DI, bạn nhận được một thể hiện của dịch vụ được truyền vào hàm tạo của bạn và lưu trữ nó. Rằng chỉ có một ví dụ duy nhất của dịch vụ này là một chi tiết triển khai. Bạn có thể dễ dàng thay đổi nó để cung cấp mã tiêu thụ khác. Bằng cách đó, bạn có một số lớp / giao diện được thực hiện bởi một thể hiện duy nhất, thay vì thực thi rằng chỉ có một thể hiện.

Điều này hữu ích nếu bạn muốn triển khai dịch vụ giả để thử nghiệm hoặc nếu các phần khác nhau của chương trình cần các cấu hình khác nhau của dịch vụ đó.


4

Vâng, bạn đúng. Thay vì truy cập vào đối tượng thông qua singleton, bạn đang chuyển một tham chiếu đến nó, do đó bạn đang sử dụng một hàm tạo.

Những gì người khác chỉ ra là những khái niệm này không liên quan. Việc sử dụng một cá thể đơn lẻ không có gì đặc biệt vì đối tượng bạn đang tiêm không thực sự quan tâm đối tượng được tiêm đến từ đâu.


2

Có một trường hợp mô hình Singleton và DI / IoC giao nhau - tiêm Singleton.

Hầu hết các khung DI có thể được cấu hình để khởi tạo một thể hiện của một đối tượng được tiêm. Bất kỳ đối tượng tiêu dùng nào yêu cầu một thể hiện của một đối tượng như vậy sẽ có cùng một thể hiện. Ví dụ đó là theo định nghĩa của một Singleton. Đó là về nó cho sự chồng chéo trong khái niệm.


1

Sự nhầm lẫn ở đây là hai khái niệm đã bị xáo trộn: singleton và accessor / gateway tĩnh đối với cá thể singleton.

Như bạn đã xác định đúng, đồng nghiệp của bạn đang đề xuất rằng phụ thuộc được chèn thay vì truy cập trực tiếp bằng cách sử dụng Singleton.Instance(cổng tĩnh).

Lý do mà điều này thực sự không liên quan gì đến mẫu singleton là vì cùng một khái niệm DI áp dụng như nhau để khởi tạo một đối tượng không đơn lẻ với new Foo(). Sự phụ thuộc sẽ được đưa vào bất kể đó là việc thực hiện đơn lẻ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.