2009-09-27 19 views
5

Aparte de la capacidad de prueba, ¿cuál es la gran ventaja de utilizar D.I. (y no estoy hablando de un marco D.I. o IoC) sobre las clases estáticas? Particularmente para una aplicación donde sabe que un servicio no será reemplazado.Además de las pruebas, ¿cómo es la Inyección de Dependencia mejor que las clases/métodos estáticos?

En una de nuestras aplicaciones C#, nuestro equipo utiliza Inyección de dependencias en la GUI web web, la capa de servicio y la capa de repositorio en lugar de utilizar métodos estáticos. En el pasado, teníamos POCO (objetos de entidad busines) que fueron creados, modificados, pasados ​​y guardados por clases estáticas.

Por ejemplo, en el pasado que podría haber escrito:

CreditEntity creditObj = CreditEntityManager.GetCredit(customerId); 
Decimal creditScore = CreditEntityManager.CalculateScore(creditObj); 
return creditScore; 

Ahora, con DI, el mismo código sería:

//not shown, _creditService instantiation/injection in c-tors 
CreditEntity creditObj = _creditService.GetCredit(customerId); 
Decimal creditScore = _creditService.CalculateScore(creditObj); 
return creditScore; 

No es muy diferente, pero ahora tenemos docenas de clases de servicio que tienen un alcance mucho más amplio, lo que significa que debemos tratarlas como si fueran estáticas (es decir, no hay variables de miembros privados a menos que se utilicen para definir otras dependencias). Además, si alguno de esos métodos utiliza un recurso (base de datos/servicio web/etc.), nos resulta más difícil gestionar problemas de concurrencia a menos que eliminemos la dependencia y utilicemos los métodos estáticos antiguos o using(...).

+5

"Además de la capacidad de prueba, ¿cuál es la gran ventaja de utilizar D.I." es como decir "aparte de tener un techo sobre mi cabeza, cuál es la gran ventaja de tener un trabajo" para mí. – TrueWill

Respuesta

5

La pregunta para D.I. podría ser: ¿es CreditEntityManager, de hecho, el lugar natural para centralizar el conocimiento sobre cómo encontrar un CreditEntity y dónde ir al CalculateScore?

Creo que la teoría de D.I. es que una aplicación modular que participan en lo X no tiene por qué conocer cómo conectar con lo Y a pesar de que X necesidades Y.

En su ejemplo, muestra el flujo de código una vez que los proveedores de servicios se han ubicado e incorporado en los objetos de datos. En ese punto, seguro, con y sin D.I. parece casi lo mismo, incluso potencialmente exactamente, lo mismo dependiendo del lenguaje de programación, estilo, etc.

La clave es cómo esos diferentes servicios se conectan entre sí. En D.I., potencialmente un objeto de un tercero esencialmente hace la gestión de configuración, pero una vez hecho esto, el código debería ser aproximadamente el mismo. El punto de D.I. no es para mejorar el código posterior, sino para tratar de hacer coincidir la naturaleza modular del problema con la naturaleza modular del programa, para evitar tener que editar los módulos y la lógica del programa que son lógicamente correctos, pero se conectan con el servicio incorrecto proveedores.

+0

Por lo tanto, para los servicios/componentes internos que no están especialmente encapsulados (es decir, nunca los cambiaríamos), D.I. no proporciona muchos beneficios? –

+1

Aún puede desear enchufar objetos y servicios simulados para pruebas unitarias. Si ya tiene un marco de prueba y nunca volverá a configurar las conexiones de servicio, o si ya tiene una arquitectura de complemento aceptable, entonces, seguro que gana sin D.I., aunque podría decirse que cualquier tipo de complemento o marco de prueba se parece al D.I. patrón de diseño. – DigitalRoss

1

Le permite intercambiar implementaciones sin abrir el código. Por ejemplo, en una de mis aplicaciones, creamos una interfaz llamada IDataService que definía métodos para consultar una fuente de datos. Para las primeras versiones de producción, utilizamos una implementación para Oracle utilizando nHibernate. Más tarde, queríamos cambiar a una base de datos de objetos, por lo que escribimos e implementamos para db4o, agregamos su ensamblaje al directorio de ejecución y cambiamos una línea en el archivo de configuración. ¡Presto! Estábamos usando db4o sin tener que descifrar el código.

1

Esto se ha discutido exactamente 1002 veces.He aquí un ejemplo de discusión que recuerdo (leído en orden):

  1. http://scruffylookingcatherder.com/archive/2007/08/07/dependency-injection.aspx
  2. http://ayende.com/Blog/archive/2007/08/18/Dependency-Injection-More-than-a-testing-seam.aspx
  3. http://kohari.org/2007/08/15/defending-dependency-injection
  4. http://scruffylookingcatherder.com/archive/2007/08/16/tilting-at-windmills.aspx
  5. http://ayende.com/Blog/archive/2007/08/18/Dependency-Injection-IAmDonQuixote.aspx
  6. http://scruffylookingcatherder.com/archive/2007/08/20/poking-bears.aspx
  7. http://ayende.com/Blog/archive/2007/08/21/Dependency-Injection-Applicability-Benefits-and-Mocking.aspx

Acerca de sus problemas particulares, parece que no está administrando correctamente sus estilos de vida de servicios ... por ejemplo, si uno de sus servicios es estable (lo que debería ser bastante raro) probablemente tenga que ser transitorio. Te recomiendo que crees tantas preguntas de SO sobre esto como necesites para despejar todas las dudas.

+0

Pero si un servicio es transitorio, ¿por qué instanciar un objeto? ¿Los objetos sin estado lógicamente no estarían mejor representados por una clase estática? –

+0

Al usar un contenedor DI solo codifica su servicio y luego configura el contenedor con el estilo de vida apropiado para cada servicio (esto también puede ser por solicitud web, por subproceso o cualquier cosa) Para hacer eso, el servicio debe ser instanciable. Por favor, crea otras preguntas si tienes dudas. –

+0

+1 para dar un recuento exacto. Jaja! – TrueWill

0

Hay un Guice video que da una buena muestra para usar D.I. Si está utilizando muchos servicios de terceros que deben conectarse dinámicamente a D. Sería de gran ayuda.

Cuestiones relacionadas