¿Por qué los contenedores IOC se consideran una forma de reducir el acoplamiento?

Estoy pensando en usar DI y Unity en mi proyecto. Y tengo una pregunta: ¿cómo reducirá el acoplamiento? Desde mi punto de vista, está aumentando de acoplamiento, porque:

  1. Necesito crear UnityContainer y registrar todos los tipos allí. Significa que necesito tener la referencia a todos los ensamblajes en ensamblaje donde se crea este contenedor.

    IUnityContainer UnityContainer;
    //....
    IUnityContainer UnityContainer= new UnityContainer();
    UnityContainer.RegisterType<IMyService, CustomerService>();
    
  2. Necesito crear una instancia de mi servicio usando Resolve, pero significa que necesito tener la referencia al ensamblaje con el contenedor.

    var service = SomeClassWithContainer.UnityContainer.Resolve<IMyService>();
    

¿He entendido mal algo o en realidad está aumentando el acoplamiento?

preguntado el 27 de agosto de 11 a las 20:08

Su pregunta parece más sobre Unity que sobre contenedores de IOC en general. ¿Quizás le gustaría actualizar su título para reflejar eso? -

@Joen Skeet: ¿Otros contenedores de COI se comportan de manera diferente? Si es así, ¿podría especificar un ejemplo con algún contenedor que no cree este acoplamiento pesado? -

Puede encontrar útil esta respuesta: stackoverflow.com/questions/5667801/… -

@Mark Seeman: gracias por el enlace, pero Nat Pryce me persuadió más de no usar contenedores IOC: natpryce.com/articles/000783.html -

Debe tener en cuenta que Nat Pryce habla de su experiencia principalmente con contenedores Java, que tienden a imponer un grado mucho mayor de acoplamiento al contenedor que el contenedor .NET típico. -

2 Respuestas

Creo que no entendió cómo se deben resolver sus dependencias.

1.) Una referencia a Unity solo debería ser necesaria en su código de arranque, que se encuentra en un soltero lugar central en su aplicación.

2.) Una vez que se realiza el arranque, todas las dependencias (idealmente) se resuelven mediante la inyección del constructor, que Unity realiza automáticamente si la clase contenedora se resuelve a través de Unity; se está filtrando por el gráfico del objeto. El ejemplo que utiliza es en realidad sólo el patrón de "localizador de servicios" y no DI.

Esto reduce el acoplamiento, ya que en lugar de crear directamente una clase concreta de la que depende su clase, "inyecta" dependencias (de nuevo, idealmente alguna abstracción como una interfaz) en su clase, lo que le permite sustituir esas dependencias con otras clases, es decir, en el escenario de prueba unitaria .

Respondido 28 ago 11, 00:08

Lo siento, pero no me da mucha información sin un buen ejemplo. Parece que todavía se necesitan referencias. - Oleg Dudnyk

@gorik: Hay un buen ejemplo de uso de Unity como IOC en mattlong.com.au/?p=142 que detalla el arranque y el desacoplamiento mediante inyección de constructor - Vidrio roto

Eso es correcto: el ensamblaje de arranque (raíz de composición) necesita hacer referencia a todos los demás ensamblajes para poder hacer el cableado. Al hacer que esta parte de la aplicación dependa de todos los demás ensamblajes, puede reducir la cantidad de acoplamiento que tienen todas las demás partes de la aplicación entre sí, lo que supera con creces los costos de tener esa complejidad en ese único lugar. - Steven

Su pregunta contiene un ejemplo del antipatrón del localizador de servicios:

public class UsesMyService
{
    private readonly IMyService _service;

    public UsesMyService()
    {
        _service = SomeClassWithContainer.UnityContainer.Resolve<IMyService>();
    }
}

Esto es fundamentalmente diferente al patrón de inyección de dependencia debido a la dirección en la que fluye la información: en el ejemplo anterior, usted se acerca y pregúntenos para el servicio, mientras que en el ejemplo siguiente, entregado el servicio:

public class UsesMyService
{
    private readonly IMyService _service;

    public UsesMyService(IMyService service)
    {
        _service = service;
    }
}

Este patrón, conocido como inyección de constructor, desacopla el UsesMyService clase a partir de detalles sobre la infraestructura circundante. Ahora, cualquiera con una implementación de IMyService puede crear instancias de UsesMyService sin tener que saber configurar una ubicación estática central.

¿Cómo sabrían siquiera qué configurar? Necesitarían el código fuente o alguna documentación que les diga que la clase depende de IMyService. El parámetro constructor expresa claramente ese requisito a los consumidores sin ninguna referencia externa.

Si sigue este patrón en todas sus bibliotecas, burbujea la responsabilidad de ensamblar los objetos hasta la capa más externa, conocida como Raíz de composición. Esta única ubicación, generalmente la clase de aplicación de nivel superior, es el único lugar con referencias a todas las bibliotecas que está utilizando. Esa es donde vive el contenedor, y ninguna otra clase en toda su solución necesita hacer referencia a él.

Respondido 28 ago 11, 06:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.