Phải, trước hết, hãy giải quyết "Bất kỳ mã nào gọi ctor sẽ cần cập nhật khi thêm phụ thuộc mới"; Để rõ ràng, nếu bạn đang thực hiện tiêm phụ thuộc và bạn có bất kỳ mã nào gọi new () trên một đối tượng có phụ thuộc, bạn đã làm sai .
Container DI của bạn sẽ có thể đưa ra tất cả các phụ thuộc có liên quan, do đó bạn không cần phải lo lắng về việc thay đổi chữ ký của hàm tạo, để đối số không thực sự giữ.
Đối với ý tưởng tiêm theo phương pháp so với mỗi phương pháp, có hai vấn đề chính với phương pháp tiêm theo phương pháp.
Một vấn đề là các phương thức của lớp của bạn nên chia sẻ các phụ thuộc, đó là một cách để đảm bảo các lớp của bạn được phân tách hiệu quả, nếu bạn thấy một lớp có số lượng phụ thuộc lớn (có thể hơn 4-5) thì lớp đó là một ứng cử viên chính để tái cấu trúc thành hai lớp.
Vấn đề tiếp theo là để "tiêm" các phụ thuộc, theo từng phương thức, bạn phải chuyển chúng vào lệnh gọi phương thức. Điều này có nghĩa là bạn sẽ phải giải quyết các phụ thuộc trước khi gọi phương thức, vì vậy bạn có thể sẽ kết thúc với một loạt mã như thế này:
var someDependency = ServiceLocator.Resolve<ISomeDependency>();
var something = classBeingInjected.DoStuff(someDependency);
Bây giờ, giả sử bạn sẽ gọi phương thức này ở 10 nơi xung quanh ứng dụng của mình: bạn sẽ có 10 đoạn trích này. Tiếp theo, giả sử bạn cần thêm một phụ thuộc khác vào DoStuff (): bạn sẽ phải thay đổi đoạn trích đó 10 lần (hoặc gói nó trong một phương thức, trong trường hợp bạn chỉ sao chép hành vi DI theo cách thủ công, đó là một sự lãng phí của thời gian).
Vì vậy, những gì bạn đã thực hiện ở đó là làm cho các lớp sử dụng DI của bạn nhận thức được thùng chứa DI của riêng chúng, đây là một ý tưởng tồi tệ , vì nó rất nhanh dẫn đến một thiết kế lộn xộn khó bảo trì.
So sánh điều đó với tiêm xây dựng; Trong tiêm chích xây dựng, bạn không bị ràng buộc với một thùng chứa DI cụ thể và bạn không bao giờ chịu trách nhiệm trực tiếp trong việc hoàn thành các phụ thuộc của các lớp của mình, vì vậy việc bảo trì khá đau đầu.
Nghe có vẻ như tôi đang cố gắng áp dụng IoC cho một lớp có chứa một loạt các phương thức của trình trợ giúp không liên quan, trong khi bạn nên tách lớp trình trợ giúp thành một số lớp dịch vụ dựa trên việc sử dụng, sau đó sử dụng trình trợ giúp để ủy quyền các cuộc gọi. Đây vẫn không phải là một cách tiếp cận tuyệt vời (người trợ giúp được phân loại với các phương thức làm bất cứ điều gì phức tạp hơn là chỉ giải quyết các đối số được truyền cho chúng thường chỉ là các lớp dịch vụ được viết kém), nhưng ít nhất nó sẽ giữ cho thiết kế của bạn sạch sẽ hơn một chút .
(NB Tôi đã thực hiện cách tiếp cận mà bạn đề xuất trước đây và đó là một ý tưởng rất tồi mà tôi đã không lặp lại kể từ đó. Hóa ra tôi đang cố tách ra các lớp thực sự không cần phải tách ra, và cuối cùng với một tập hợp các giao diện trong đó mỗi cuộc gọi phương thức yêu cầu một lựa chọn gần như cố định các giao diện khác. Đó là một cơn ác mộng để duy trì.)