Khi tạo thành phần .NET có thể thiết kế, bạn được yêu cầu cung cấp hàm tạo mặc định. Từ các tài liệu IComponent:Cách kết hợp các thành phần có thể thiết kế với việc tiêm phụ thuộc
Để trở thành một thành phần, một lớp phải thực hiện các giao diện IComponent và cung cấp một constructor cơ bản mà không cần tham số hoặc một tham số duy nhất của loại iContainer.
Điều này khiến không thể thực hiện việc tiêm phụ thuộc thông qua các đối số của hàm tạo. (Constructors tắm có thể được cung cấp, nhưng các nhà thiết kế sẽ bỏ qua chúng.) Một số lựa chọn thay thế, chúng tôi đang cân nhắc:
Service Locator
Đừng sử dụng dependency injection, thay vì sử dụng các mô hình dịch vụ định vị để có được sự phụ thuộc. Điều này có vẻ là những gì IComponent.Site. GetService dành cho. Tôi đoán chúng ta có thể tạo một triển khai ISite có thể tái sử dụng (ConfigurableServiceLocator?) Có thể được cấu hình với các phụ thuộc cần thiết. Nhưng làm thế nào điều này làm việc trong một bối cảnh thiết kế?
Dependency Injection thông qua thuộc tính
Tiêm phụ thuộc qua các thuộc tính. Cung cấp các trường hợp mặc định nếu chúng là cần thiết để hiển thị thành phần trong thiết kế . Tài liệu có thuộc tính cần được tiêm.
Tiêm phụ thuộc với một phương pháp Initialize
Đây là giống như tiêm qua thuộc tính nhưng nó giữ danh sách các phụ thuộc mà cần phải được tiêm ở một nơi. Bằng cách này, danh sách các phụ thuộc bắt buộc được ghi lại hoàn toàn, và trình biên dịch sẽ hỗ trợ bạn với các lỗi khi danh sách thay đổi.
Bất kỳ ý tưởng nào là phương pháp hay nhất ở đây? Bạn làm nó như thế nào?
chỉnh sửa: Tôi đã gỡ bỏ "(ví dụ một WinForms UserControl)" kể từ khi tôi có ý định câu hỏi để được về thành phần nói chung. Các thành phần là tất cả về đảo ngược kiểm soát (xem phần 8.3.1 của UMLv2 specification) vì vậy tôi không nghĩ rằng "bạn không nên tiêm bất kỳ dịch vụ" là một câu trả lời tốt.
chỉnh sửa 2: Phải mất một số chơi với WPF và mô hình MVVM để cuối cùng "nhận được" câu trả lời của Mark. Tôi thấy rằng các điều khiển trực quan thực sự là một trường hợp đặc biệt. Đối với việc sử dụng các thành phần không nhìn thấy trên bề mặt thiết kế, tôi nghĩ mô hình thành phần .NET cơ bản không tương thích với việc tiêm phụ thuộc. Dường như nó được thiết kế xung quanh mẫu định vị dịch vụ thay thế. Có lẽ điều này sẽ bắt đầu thay đổi với cơ sở hạ tầng đã được thêm vào .NET 4.0 trong không gian tên System.ComponentModel.Composition.
Nếu tôi giải thích câu trả lời của bạn một cách chính xác, bạn đang nói rằng các điều khiển không được sử dụng bất kỳ dịch vụ nào. Tôi không chắc tôi đồng ý. Ví dụ, tôi có một điều khiển mà không hiển thị văn bản trực tiếp bằng cách gọi System.Windows.Forms.TextRenderer. Thay vào đó, nó sử dụng một dịch vụ ITextRenderer được tiêm (với các phương thức cơ bản giống nhau). Điều này cho phép tôi thực hiện các chiến lược viết tắt ưa thích vượt ra ngoài những gì được cung cấp bởi khung công tác .NET, trong khi vẫn giữ mã như vậy độc lập khỏi bản thân kiểm soát. –
Có, tôi nói rằng Điều khiển không nên sử dụng dịch vụ - dịch vụ nên sử dụng Điều khiển. Điều khiển không nên làm gì ngoài giao diện người dùng. Nó là tốt mà bạn có thể tiêm chiến lược viết tắt ưa thích, nhưng logic như vậy thuộc về (View) Model, không phải trong View chính nó. Sau đó bạn có thể databind View của bạn thành các thuộc tính trên mô hình tạo ra các giá trị mong muốn bằng cách gọi các phụ thuộc được tiêm. Mặc dù bạn dường như đang sử dụng WinForms, hãy kiểm tra điều này để lấy cảm hứng: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx –