Al crear un componente designado de .NET, debe proporcionar un constructor predeterminado. Desde el IComponent documentación:Cómo combinar componentes identificables con la inyección de dependencia
siendo un componente, una clase debe implementar la interfaz IComponent y proporcionar un constructor básico que requiere ningún parámetro o un único parámetro de tipo IContainer.
Esto hace que sea imposible hacer la inyección de dependencia a través de los argumentos del constructor. (Constructores adicionales podrían proporcionarse, pero el diseñador se ignoran.) Algunas alternativas que estamos considerando:
Servicio de Localización de
No utilizar la inyección de dependencia, en lugar de utilizar el modelo de servicio de localización para adquirir dependencias. Esto parece ser lo que IComponent.Site. GetService es para. Supongo que podríamos crear una implementación ISite reutilizable (ConfigurableServiceLocator?) Que se puede configurar con las dependencias necesarias. Pero, ¿cómo funciona esto en un contexto de diseñador?
inyección de dependencia a través de propiedades
dependencias Inyectar a través de propiedades. Proporcione las instancias predeterminadas si son necesarias para mostrar el componente en un diseñador . Documente qué propiedades se deben inyectar .
dependencias Inyectar con un método Inicializar
Esto es muy parecido inyección a través de propiedades, pero que mantiene la lista de dependencias que necesitan ser inyectado en un solo lugar. De esta forma, la lista de dependencias requeridas se documenta implícitamente, y el compilador le ayudará con los errores cuando la lista cambie.
¿Alguna idea de cuál es la mejor práctica aquí? ¿Cómo lo haces?
editar: He eliminado "(por ejemplo, un WinForms UserControl)", ya que pretendía la cuestión que se acerca de los componentes en general. Los componentes tienen que ver con la inversión del control (consulte la sección 8.3.1 del UMLv2 specification), por lo tanto, no creo que "no debe inyectar ningún servicio" es una buena respuesta.
edición 2: Tomó un poco de juego con WPF y el patrón MVVM a fin de "obtener" la respuesta de la marca. Ahora veo que los controles visuales son un caso especial. En cuanto al uso de componentes no visuales en las superficies de diseñador, creo que el modelo de componente .NET es fundamentalmente incompatible con la inyección de dependencia. Parece estar diseñado alrededor del patrón de localizador de servicio. Quizás esto comience a cambiar con la infraestructura que se agregó en .NET 4.0 en el espacio de nombres System.ComponentModel.Composition.
Si estoy interpretando su respuesta correctamente, usted está diciendo que los controles no deberían usar ningún servicio. No estoy seguro de estar de acuerdo. Por ejemplo, tengo un control que no representa el texto directamente llamando a System.Windows.Forms.TextRenderer. En cambio, usa un servicio inyectable ITextRenderer (básicamente con los mismos métodos). Esto me permite implementar estrategias de abreviatura sofisticadas más allá de lo que proporciona el framework .NET, al tiempo que mantengo ese código independiente del control en sí mismo. –
Sí, digo que los controles no deberían usar servicios; los servicios deberían usar controles. Un control no debería hacer más que representar UI. Está bien que pueda inyectar estrategias de abreviatura sofisticadas, pero dicha lógica pertenece al Modelo (de Vista), no a la Vista en sí. A continuación, puede vincular su vista a las propiedades en el modelo que produce los valores deseados invocando las dependencias inyectadas. Aunque parece que está utilizando WinForms, consulte esto en busca de inspiración: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx –