Thông thường khi tôi cần tiêm một hoặc nhiều dịch vụ vào một dịch vụ khác, tôi tiêm một cách rõ ràng mỗi dịch vụ. Tuy nhiên, tôi có một tình huống mà việc tự tiêm chích dịch vụ sẽ thực sự làm mọi thứ dễ dàng hơn. Tôi biết đây không phải là một thực hành được đề nghị, nhưng tôi tò mò những lý do kỹ thuật là gì để ngăn cản điều này. Nó có phải là một cái gì đó hợp pháp như nó quá mã nguồn lực, hoặc một cảm giác cá nhân hơn rằng nó quá lộn xộn?Những lý do kỹ thuật nào để tránh tiêm chích chứa dịch vụ thay vì các dịch vụ cá nhân?
Trả lời
Nếu bạn tiêm bình chứa, bạn không làm cho phụ thuộc rõ ràng. Trong thực tế, bạn đang che khuất chúng nhiều hơn trước. Nếu bạn có một lớp học như thế này ...
class DocumentCreator(IFileNamer fileNamer, IRepository repository)
{ ... }
... bạn có thể xem phụ thuộc là gì. Bạn cũng có thể dễ dàng giả lập các phụ thuộc đó để kiểm thử đơn vị, để đảm bảo rằng bạn tách biệt DocumentCreator và có thể biết rằng bất kỳ lỗi thử nghiệm nào là kết quả của mã của nó chứ không phải là mã trong một trong các phụ thuộc của nó.
Nếu, mặt khác, bạn làm điều này ...
class DocumentCreator(IDependencyContainer container)
{ ... }
... bạn đã che khuất sự phụ thuộc. Bạn không thể biết, mà không kiểm tra nội bộ của lớp, rằng nó đòi hỏi một IFileNamer và một IRepository.
Bạn cũng không thể dễ dàng biết được những gì bạn cần đặt trong thùng chứa để kiểm tra DocumentCreator. Giả mạo IDependencyContainer sẽ không giúp bạn chút nào; lớp của bạn sẽ vẫn không thành công khi thử nghiệm vì vùng chứa sẽ không chứa IFileNamer và IRepository, trừ khi bạn kiểm tra các lớp bên trong của lớp để thấy rằng chúng được yêu cầu.
Tôi nghĩ rằng vấn đề chính với cách tiếp cận này là bạn không thấy phụ thuộc rõ ràng nữa. Một vấn đề khác có thể là khó kiểm tra hơn.
Những gì bạn mô tả là ServiceLocator. Đây được coi là một mô hình chống trong thiết kế ứng dụng hiện đại. This article mô tả lý do.
Sai. Mọi người thực sự cần phải ngừng liên kết với blog của anh chàng đó. Đây là cái nhìn sâu sắc từ một bậc thầy có kỹ năng hơn. http://www.martinfowler.com/articles/injection.html – Colin
@Colin Bạn đã bao giờ đọc lý do Mark Seemann tuyên bố ServiceLocator là một mô hình chống lại? Bạn chỉ đạt được một vài lợi thế của việc tiêm phụ thuộc đầy đủ nhưng bỏ lỡ một vài lợi ích (tức là khả năng hiển thị tức thì của các phụ thuộc). Tôi bổ sung SL vi phạm các quy tắc khác nhau về thiết kế phần mềm như gói gọn http://blog.ploeh.dk/2015/10/26/service-locator-violates-encapsulation/ hoặc SOLID http://blog.ploeh.dk/2014/05/15/service-locator-violates-solid/ –
Có, và nó là vô nghĩa. Trong thực tế, đối lập của lập luận của ông là đúng sự thật. Ví dụ, anh ta nói nó "đóng gói chiến dịch", nhưng toàn bộ điểm đóng gói là che giấu các chi tiết bên trong của lớp mà người gọi không nên quan tâm (như xác thực, mà anh ta bên ngoài trong ví dụ của mình). DI có các ứng dụng và lợi ích rõ ràng nhưng nó không phải là "búa vàng"; Đó là một mô hình chống. Hãy suy nghĩ nếu bạn phải vượt qua TraceListeners mỗi khi bạn gọi Trace.WriteLine() hoặc Debug.WriteLine()! Tôi ước mọi người sẽ dừng việc đối xử với ông Seeman như một chuyên gia; anh ấy chỉ là một blogger được đánh giá cao. – Colin
- 1. Dịch vụ WCF thay vì Dịch vụ Web ASMX?
- 2. JAX-WS Các kỹ thuật khách hàng đồng bộ để gọi các dịch vụ web
- 3. Tiêm Twig làm dịch vụ trong Symfony2
- 4. Sự khác nhau giữa các dịch vụ RDP/Terminal và các kỹ thuật trực tuyến VNC
- 5. Tiêm dữ liệu vào dịch vụ WCF
- 6. Chạy dịch vụ WCF hiển thị danh sách thư mục thay vì dịch vụ
- 7. Tiêm dịch vụ phụ thuộc khi kiểm tra đơn vị Dịch vụ AngularJS
- 8. Dịch vụ Tiêm trong Grails Unit Test
- 9. Những lý do kỹ thuật đằng sau "Itanium fiasco", nếu có?
- 10. Thêm dịch vụ vào dịch vụ chuyển tên dịch vụ
- 11. Dịch vụ web Java, ngày xsd thay vì ngày giờ
- 12. Dịch vụ RIA .NET/Dịch vụ WCF
- 13. Thời gian thay vì datetime trong Dịch vụ báo cáo
- 14. Dịch vụ WSDL cho XML thuần thay vì SOAP
- 15. Các phiên dịch vụ và tin nhắn dịch vụ Azure
- 16. C# Dịch vụ Windows Thay thế
- 17. ZF2 dịch vụ định vị & phụ thuộc tiêm
- 18. Dependency Injection, tiêm một đối tượng "tiêm" (dịch vụ) vào một newable (thực thể)
- 19. Dịch vụ WCF và Dịch vụ Windows
- 20. InvalidOperationException trong khi tạo cá thể dịch vụ web wcf
- 21. Dịch vụ web của Amazon có được định giá hợp lý cho một máy chủ cá nhân không?
- 22. Tại sao một người sử dụng REST thay vì các dịch vụ dựa trên SOAP?
- 23. Dịch vụ báo cáo 2008 R2 dịch vụ web api - làm cách nào để quản lý quyền bảo mật?
- 24. Các dịch vụ giả lập bên trong một dịch vụ lò xo khác với mockito
- 25. . Net Tiêu thụ Dịch vụ Web: Các loại giống nhau trong hai dịch vụ khác nhau
- 26. Tiêm lời hứa được giải quyết vào dịch vụ
- 27. Xử lý onActivityResult trên Dịch vụ
- 28. Grails 2.x tiêm dịch vụ trong Groovy/src
- 29. Dịch vụ WCF phơi bày DTO hoặc Pháp nhân
- 30. Dịch vụ RIA và ADO.NET Dịch vụ dữ liệu
Tôi chắc chắn đồng ý với phần đầu tiên, và đó là lý do tại sao ngoại trừ những trường hợp hiếm hoi mà tôi vẫn tiếp tục tiêm các dịch vụ cụ thể. Nhưng tôi không chắc làm thế nào thử nghiệm nó sẽ khó khăn hơn? –
Nó sẽ ngụ ý tạo đối tượng vùng chứa và tiêm các dịch vụ giả lập (hoặc không được mô phỏng) vào nó, thay vì tiêm chúng trực tiếp, tạo thêm một bước nữa. – greg0ire
Hmm, đó chắc chắn là một bất lợi lớn. –