Vùng chứa IoC thường hữu ích khi tiêm đối tượng có trạng thái; hoặc các lớp hoặc các giao diện có nhiều hơn một triển khai thực hiện, ngay cả khi triển khai thứ hai là một mô hình cho mục đích thử nghiệm. Nếu cả hai điều này đều không đúng, bạn sẽ không đạt được gì bằng cách tiêm nó.thành ngữ phổ biến nhất trong những ngày này là để lớp của bạn được giao diện bởi một giao diện mà việc triển khai thực và giả có thể thực hiện cả hai.
1) Phương pháp tĩnh trên lớp trợ giúp - Không, chúng thường không được IoC tiêm. Thông thường họ là những tiện ích không quốc tịch.
Để sử dụng một ví dụ rất đơn giản, bạn không cần hai phiên bản của phương thức tiện ích được gọi là StringUtils.Reverse()
. Bạn chỉ cần một, và bạn có thể dễ dàng viết các bài kiểm tra xung quanh nó bởi vì nó không có trạng thái hoặc phụ thuộc, do đó, hoàn toàn không có lợi ích để chế giễu nó ra. Ví dụ kiểm tra:
string reversedString = StringUtils.Reverse("input");
Assert.AreEqual("tupni", reversedString)
Nếu tiện ích không phải là thực sự không quốc tịch (ví dụ phụ thuộc vào HttpContext.Current), sau đó bạn nên làm cho sự phụ thuộc rõ ràng bằng cách tiêm nó, và không thực hiện các tiện ích tĩnh.
2) Singletons: Thường thì có, đơn được tiêm. Nhưng một điều tốt về IoC là bạn lo lắng ít hơn về việc liệu chỉ có một thứ gì đó hay không. Bạn có được sự linh hoạt trong instancing bằng cách sử dụng IoC. Quyết định có một kiểu cụ thể là singleton hoặc instance mới mỗi lần trở thành một phần của cấu hình container IoC và không có gì khác trong mã cần phải thay đổi.
Vì vậy, singleton-hood dừng lại là một mối quan tâm riêng biệt phải được mã hóa vào lớp (và các lớp có nhiều mối quan tâm khi chúng không phải là xấu), và nó trở thành mối quan tâm của container IoC. Bạn không mã hóa lớp "như một singleton" với bất kỳ thứ gì đặc biệt như một hàm tạo riêng và phương thức public static GetInstance()
nữa, bạn chỉ cần mã nó cho mối quan tâm chính, trong khi cấu hình của thùng chứa IoC chỉ định nếu nó là một singleton hay không, hoặc ở đâu đó ở giữa, như một ví dụ cho mỗi chủ đề.
3) Lớp tĩnh - là nơi tự nhiên cho phương pháp tĩnh. Cân nhắc tạo các phương thức mở rộng phương thức tĩnh khi thích hợp. Bạn không thể tiêm các lớp này, vì bạn không thể tạo chúng. Sử dụng các lớp tĩnh làm cho mã thủ tục không hướng đối tượng. Đây không phải là một điều xấu đối với các phương thức trợ giúp nhỏ, nhưng nếu phần lớn mã là như vậy, thì bạn không sử dụng các tính năng OO mạnh mẽ của nền tảng .Net.
cảm ơn Bryan - Điều này có nghĩa là có thể có thêm một số chi phí của IOC xây dựng những thứ (ví dụ như logger) mọi lúc? Ngoài ra đối với các lớp loại utils, tôi tự hỏi điều này sẽ làm cho tái cấu trúc khó hơn khi bạn cấu trúc lại các hàm trợ giúp của bạn giữa các lớp trợ giúp của bạn? (Tôi đang sử dụng ReSharper bản thân mình) - cảm ơn – Greg
Hầu hết các container IoC cho phép một số loại phạm vi. Bằng cách này, tôi có nghĩa là bạn chỉ ra cho dù đối tượng của bạn được tạo ra mỗi lần (nhà máy), tạo ra một lần cho mỗi bối cảnh (đơn vị công việc), hoặc một lần cho mỗi ứng dụng (singleton). Điều này có nghĩa là bạn có thể đăng ký logger sao cho nó chỉ được tạo một lần. –
Cuối cùng bạn muốn loại bỏ các lớp tiện ích. Mỗi phương thức trên mỗi lớp đó có cùng các vấn đề liên kết như phương thức 'HttpUtils.DoStuff' ở trên. Vì lý do đó, bạn không muốn yêu cầu * bất kỳ * mã nào phụ thuộc trực tiếp vào các thành viên 'static'. Thay vào đó, lấy phần thân của 'HttpUtils.DoStuff', đặt nó đằng sau' IDoesStuff' và xóa hoàn toàn phương thức từ 'HttpUtils'. Bây giờ, bất kỳ lớp nào có thể được gọi là phương thức tĩnh có thể thay thế chấp nhận 'IDoesStuff' trong hàm tạo của nó. Viola: không cần thiết cho lớp tiện ích! –