Un contenedor IoC suele ser útil para inyectar objetos que tienen estado; o clases o interfaces que tienen más de una implementación, incluso si la segunda implementación es una simulación para fines de prueba. Si ninguno de estos es verdadero, no obtienes nada al inyectarlo.el idioma más común en estos días es tener a tu clase frente a una interfaz que la implementación real y simulada pueda implementar.
1) Métodos estáticos en las clases de ayuda - No, estos no suelen ser inyectados por IoC. Típicamente son utilidades sin estado.
Para utilizar un ejemplo muy simple, no necesita dos versiones de un método de utilidad llamado StringUtils.Reverse()
. Solo necesita uno, y puede escribir pruebas fácilmente porque no tiene estado o dependencias, por lo que no hay ningún beneficio para burlarse de él. Ejemplo de prueba:
string reversedString = StringUtils.Reverse("input");
Assert.AreEqual("tupni", reversedString)
Si la utilidad no es realmente sin estado (por ejemplo, depende de HttpContext.Current), entonces usted debe hacer explícita la dependencia mediante la inyección, y no hacer la utilidad estática.
2) Singletons: A menudo sí, se inyectan los singletons. Pero una cosa buena de IoC es que te preocupas menos si solo hay uno de algo o no. Usted gana flexibilidad en la creación de instancias usando IoC. La decisión de tener un tipo particular como singleton o nueva instancia cada vez se convierte en parte de la configuración del contenedor IoC y nada más en el código necesita cambiar.
Así que singleton-hood deja de ser una preocupación separada que tiene que codificarse en la clase (y las clases que tienen varias preocupaciones cuando no es necesario) es una preocupación del contenedor IoC. Ya no codificas la clase "como singleton" con nada especial como un constructor privado y un método public static GetInstance()
, solo lo codificas para la preocupación principal, mientras que la configuración del contenedor IoC especifica si es un singleton o no, o en algún lugar en el medio, como una instancia por hilo.
3) Las clases estáticas - son el hogar natural de los métodos estáticos. Considere hacer métodos de extensión de métodos estáticos cuando sea apropiado. No puede inyectar estas clases, ya que no puede crearlas. Usar clases estáticas hace que el código de procedimiento no esté orientado a objetos. Esto no es malo para los pequeños métodos de ayuda, pero si la mayoría del código es así, entonces no está usando las poderosas características OO de la plataforma .Net.
gracias Bryan - ¿Esto significa que podría haber un poco más de sobrecarga del COI construyendo cosas (por ejemplo, registrador) cada vez? También para las clases de tipo utils, me pregunto ¿esto hará que la refactorización sea más difícil a medida que refactoriza sus funciones de ayuda entre las clases de ayuda? (Estoy usando ReSharper) - gracias – Greg
La mayoría de los contenedores IoC permiten algún tipo de alcance. Con esto, me refiero a que indique si su objeto se crea cada vez (de fábrica), creado una vez por contexto (unidad de trabajo), o una vez por aplicación (singleton). Esto significa que puede registrar el registrador de manera que solo se crea una vez. –
En última instancia, desea eliminar las clases de utilidad. Cada método en cada una de esas clases tiene los mismos problemas de acoplamiento que el método 'HttpUtils.DoStuff' anterior. Por ese motivo, no es necesario que el código * any * dependa directamente de los miembros 'static'. En su lugar, tome el cuerpo de 'HttpUtils.DoStuff', póngalo detrás de' IDoesStuff', y elimine completamente el método de 'HttpUtils'. Ahora, cualquier clase que pueda haber llamado el método estático puede aceptar 'IDoesStuff' en su constructor. Viola: ¡ya no es necesario para la clase de utilidad! –