This question about unit testing best practices đề cập đến việc thiết kế các lớp để tiêm phụ thuộc. Điều này khiến tôi suy nghĩ về chính xác điều đó có ý nghĩa gì.Hướng dẫn thiết kế các lớp cho tiêm phụ thuộc
Chỉ mới bắt đầu làm việc với đảo ngược các thùng chứa kiểm soát Tôi có một số ý tưởng về vấn đề này, vì vậy hãy để tôi ném chúng vào tường và xem những gì dính.
Cách tôi nhìn thấy, có ba loại phụ thuộc cơ bản mà một đối tượng có thể có.
- Đối tượng phụ thuộc - Đối tượng thực tế sẽ được lớp đó sử dụng. Ví dụ LogInVerifier trong một LogInFormController. Chúng nên được tiêm vào thông qua hàm tạo. Nếu lớp đó là đủ cao, nó đòi hỏi nhiều hơn 4 trong số các đối tượng này trong constructor xem xét phá vỡ nó lên hoặc ít nhất là bằng cách sử dụng một mẫu nhà máy. Bạn cũng nên xem xét việc cung cấp sự phụ thuộc với một giao diện và mã hóa dựa trên giao diện.
- Cài đặt đơn giản - Ví dụ: ngưỡng hoặc khoảng thời gian chờ. Các giá trị này thường có giá trị mặc định và được đặt thông qua trình tạo mẫu nhà máy. Bạn cũng có thể cung cấp quá tải khởi tạo để thiết lập chúng. Tuy nhiên, trong hầu hết các trường hợp, có lẽ bạn không nên ép buộc khách hàng phải thiết lập một cách rõ ràng.
- Đối tượng tin nhắn - Một đối tượng được chuyển từ lớp này sang lớp khác mà lớp nhận được có lẽ sử dụng cho logic nghiệp vụ. Một ví dụ sẽ là một đối tượng User cho một lớp LogInCompleRouter. Ở đây tôi thấy nó thường tốt hơn cho thông điệp không được chỉ định trong constructor vì bạn sẽ phải đăng ký cá thể User với IoC Container (làm cho nó toàn cục) hoặc không khởi tạo LogInCompleteRouter cho đến sau khi bạn có một cá thể của User (mà bạn không thể sử dụng DI hoặc ít nhất sẽ cần một sự phụ thuộc rõ ràng trên Container). Trong trường hợp này, tốt hơn là nên truyền đối tượng tin nhắn chỉ khi bạn cần nó cho lời gọi phương thức (ví dụ: LoginInCompleteRouter.Route (User u);).
Ngoài ra, tôi nên đề cập đến mà không mọi thứ nên DI'ed, nếu bạn có một chút đơn giản của chức năng đó chỉ là thuận tiện đến yếu tố ra một lớp ném đi, nó có lẽ là ok để nhanh chóng ngay tại chỗ. Rõ ràng đây là một cuộc gọi phán xét; nếu tôi thấy nó thích hợp để viết một lớp học như
class PasswordEqualsVerifier {
public bool Check(string input, string actual) { return input===actual;}
}
Tôi có thể sẽ không phụ thuộc vào việc tiêm nó và chỉ có một đối tượng khởi tạo trực tiếp bên trong khối sử dụng. Hệ quả là nếu nó là giá trị viết bài kiểm tra đơn vị cho, sau đó nó có thể là giá trị tiêm.
Vì vậy, các bạn nghĩ sao? Bất kỳ hướng dẫn bổ sung hoặc ý kiến tương phản đều được hoan nghênh.