inyeccion injection ejemplo dependency dependencias control dependency-injection

dependency-injection - injection - inyeccion de dependencias php



¿Cuándo usas la inyección de dependencia? (9)

He estado usando StructureMap recientemente y he disfrutado la experiencia a fondo. Sin embargo, puedo ver cómo uno puede dejarse llevar fácilmente interconectando todo y terminar con clases que llevan una gran cantidad de interfaces a sus constructores. A pesar de que realmente no es un gran problema cuando se utiliza un marco de inyección de dependencia, todavía se siente que hay ciertas propiedades que realmente no necesitan ser interconectadas solo por el hecho de interconectarlas.

¿Dónde trazar la línea sobre qué interfaz interactuar vs simplemente agregar una propiedad a la clase?


¿Qué quieres decir con "solo agregar una propiedad a una clase"?

Mi regla de oro es hacer que la unidad de clase sea comprobable. Si su clase depende de los detalles de implementación de otra clase, debe ser refactorizada / abstraída hasta el punto de que las clases se puedan probar de forma aislada.

EDITAR: Usted menciona una carga de interfaces en el constructor. Aconsejaría utilizar setters / getters en su lugar. Me parece que hace las cosas mucho más fáciles de mantener a largo plazo.


Lo hago solo cuando ayuda con la separación de preocupaciones.

Al igual que quizás el proyecto cruzado, proporcionaría una interfaz para los implementadores en uno de mis proyectos de biblioteca y el proyecto de implementación inyectaría cualquier implementación específica que quisieran.

Pero eso es todo ... todos los demás casos solo harían el sistema innecesariamente complejo


Otro elemento con el que lucho es dónde debo usar la inyección de dependencia? ¿Dónde tomas tu dependencia en StructureMap? ¿Solo en la aplicación de inicio? ¿Eso significa que todas las implementaciones se deben pasar desde la capa superior a la capa inferior?


Piensa en tu diseño. DI le permite cambiar el funcionamiento de su código a través de cambios de configuración. También le permite romper las dependencias entre clases para que pueda aislar y probar objetos más fácilmente. Debes determinar dónde tiene sentido esto y dónde no. No hay una respuesta fácil.

Una buena regla general es que si es demasiado difícil de probar, tiene algunos problemas con la responsabilidad única y las dependencias estáticas. Aísle el código que realiza una única función en una clase y rompa esa dependencia estática extrayendo una interfaz y usando un marco DI para inyectar la instancia correcta en el tiempo de ejecución. Al hacer esto, haces que sea trivial probar las dos partes por separado.


Incluso con todos los hechos y procesos en el mundo ... cada decisión se reduce a una decisión: ¿Olvidé dónde lo leí?
Creo que es más una llamada de experiencia / tiempo de vuelo. Básicamente, si ve la dependencia como un objeto candidato que puede ser reemplazado en el futuro cercano, use la inyección de dependencia. Si veo ''classA y sus dependencias'' como un bloque para la sustitución, entonces probablemente no use DI para los deps.


El mayor beneficio es que lo ayudará a comprender o incluso a descubrir la arquitectura de su aplicación. Podrá ver muy claramente cómo funcionan sus cadenas de dependencia y podrá realizar cambios en las partes individuales sin que sea necesario cambiar las cosas que no están relacionadas. Usted terminará con una aplicación débilmente acoplada. Esto lo impulsará a un mejor diseño y se sorprenderá cuando pueda seguir mejorando porque su diseño lo ayudará a seguir separando y organizando el código en el futuro. También puede facilitar las pruebas unitarias porque ahora tiene una forma natural de sustituir implementaciones de interfaces particulares.

Hay algunas aplicaciones que son simplemente desechables, pero si hay una duda, seguiré adelante y crearé las interfaces. Después de un poco de práctica, no es una gran carga.


Uso Castle Windsor / Microkernel, no tengo experiencia con nada más pero me gusta mucho.

¿En cuanto a cómo decides qué inyectar? Hasta ahora, la siguiente regla práctica me ha funcionado bien: si la clase es tan simple que no necesita pruebas unitarias, puede crear una instancia en clase, de lo contrario, probablemente desee tener una dependencia a través del constructor.

En cuanto a si debe crear una interfaz o solo hacer que sus métodos y propiedades sean virtuales, creo que debería ir por la ruta de la interfaz ya sea si a) puede ver que la clase tiene algún nivel de reutilización en una aplicación diferente (es decir, un registrador) ob ) ya sea por la cantidad de parámetros del constructor o porque hay una cantidad significativa de lógica en el constructor, la clase es, por lo demás, difícil de simular.


La inyección de dependencia solo se debe usar para las partes de la aplicación que se deben cambiar dinámicamente sin volver a compilar el código base

DI debe usarse para aislar su código de recursos externos (bases de datos, servicios web, archivos xml, arquitectura de complementos). La cantidad de tiempo que tomaría probar su lógica en el código sería casi prohibitivo en muchas compañías si está probando componentes que DEPENDAN de una base de datos.

En la mayoría de las aplicaciones, la base de datos no cambiará dinámicamente (aunque podría), pero en términos generales, casi siempre es una buena práctica NO vincular su aplicación a un recurso externo en particular. El monto involucrado en el cambio de recursos debe ser bajo (las clases de acceso a los datos rara vez deben tener una complejidad ciclomática superior a uno en sus métodos).


El principal problema con la inyección de dependencia es que, aunque da la apariencia de una arquitectura débilmente acoplada, en realidad no es así.

Lo que realmente está haciendo es mover ese acoplamiento desde el tiempo de compilación al tiempo de ejecución, pero aun así, si la clase A necesita alguna interfaz B para funcionar, todavía debe proporcionarse una instancia de una clase que implemente la interfaz B.

La inyección de dependencia solo se debe usar para las partes de la aplicación que se deben cambiar dinámicamente sin volver a compilar el código base.

Usos que he visto útiles para un patrón de inversión de control:

  • Una arquitectura de complemento. Entonces, al hacer los puntos de entrada correctos, puede definir el contrato para el servicio que debe proporcionarse.
  • Arquitectura tipo flujo de trabajo. Donde puede conectar varios componentes conectando dinámicamente la salida de un componente a la entrada de otro.
  • Aplicación por cliente Digamos que tiene varios clientes que pagan por un conjunto de "características" de su proyecto. Al usar la inyección de dependencia, puede proporcionar fácilmente solo los componentes principales y algunos componentes "agregados" que proporcionan solo las características que el cliente ha pagado.
  • Traducción. Aunque esto no suele hacerse con fines de traducción, puede "inyectar" diferentes archivos de idioma según lo necesite la aplicación. Eso incluye interfaces de usuario RTL o LTR según sea necesario.