dependency injection - que - Dependencia-Inyección para resolver dependencias circulares
que es inyección de dependencias en spring (1)
No , un Contenedor DI no resolverá una dependencia circular ; de hecho, protestará contra ella emitiendo excepciones cuando intente resolver las dependencias.
En muchos de los Contenedores DI puede proporcionar una configuración avanzada que le permite superar este problema, pero por sí mismos no pueden resolver las dependencias circulares. ¿Como pudireon?
Como regla general, una dependencia circular es un olor de diseño . Si puede, considere un diseño alternativo donde se deshaga de la dependencia circular, esto también le dará menos acoplamiento . Algunas posibles alternativas de rediseño:
- Usa eventos para señalar de una clase a otra. A menudo, una dependencia circular ya va en una dirección, y cuando este es el caso, modelar parte de esta API de señalización como eventos puede cortar el círculo.
- Si lo anterior es cierto, pero siente que los eventos parecen incorrectos, puede considerar aplicar el patrón Observer .
- Si la comunicación debe ir realmente en ambos sentidos, puede usar un Mediador a través del cual los componentes se puedan comunicar.
Sin embargo, escogí deliberadamente la palabra " olor sobre anti-patrón" , ya que hay casos de esquina (especialmente cuando se trata de API definidas externamente) donde las dependencias circulares no se pueden evitar.
En tales casos, debe decidir dónde aflojar ligeramente la creación de la dependencia. Una vez que lo sepa, la inyección de una fábrica abstracta puede ser útil para diferir una de las creaciones hasta que se hayan creado las otras partes del círculo.
Esta otra respuesta es el mejor ejemplo disponible del que estoy al tanto, pero si puedo ser tan audaz, mi próximo libro también contendrá una sección que aborda este tema.
Ejemplo:
class MyClass
{
Composition m_Composition;
void MyClass()
{
m_Composition = new Composition( this );
}
}
Estoy interesado en usar depenency-injection aquí. Así que tendré que refactorizar el constructor a algo como:
void MyClass( Composition composition )
{
m_Composition = composition;
}
Sin embargo, ahora tengo un problema, ya que el objeto Composition
basa en el objeto de tipo MyClass
que acaba de crearse.
¿Puede un contenedor de dependencia resolver esto? ¿Se supone que debe hacerlo?
¿O es solo un mal diseño desde el principio?