¿Cuál es el propósito de los contenedores de COI? Las razones combinadas pueden simplificarse de la siguiente manera:
Cuando se utilizan los principios de desarrollo OOP / SOLID, la inyección de dependencias se vuelve desordenada. O tiene los puntos de entrada de nivel superior que administran dependencias para múltiples niveles por debajo de sí mismos y pasan dependencias recursivamente a través de la construcción, o tiene un código algo duplicado en los patrones e interfaces de fábrica / constructor que construyen dependencias según las necesite.
No hay una forma OOP / SOLID de realizar esto Y tener un código súper bonito.
Si esa afirmación anterior es verdadera, ¿cómo lo hacen los contenedores IOC? Hasta donde sé, no están empleando alguna técnica desconocida que no se puede hacer con DI manual. Por lo tanto, la única explicación es que los Contenedores de COI rompen los Principios de POO / SÓLIDO mediante el uso de accesos privados de objetos estáticos.
¿Los contenedores IOC rompen los siguientes principios detrás de escena? Esta es la verdadera pregunta ya que entiendo bien, pero tengo la sensación de que alguien más tiene una mejor comprensión:
- Control de alcance . El alcance es la razón de casi todas las decisiones que tomo sobre el diseño de mi código. Bloque, Local, Módulo, Estático / Global. El alcance debe ser muy explícito, tanto a nivel de bloque como lo menos posible en Estático. Debería ver declaraciones, instancias y finalizaciones del ciclo de vida. Confío en el lenguaje y el GC para administrar el alcance siempre que sea explícito con él. En mi investigación, descubrí que los contenedores IOC configuran la mayoría o todas las dependencias como estáticas y las controlan a través de alguna implementación de AOP detrás de escena. Entonces nada es transparente.
- La encapsulación . ¿Cuál es el propósito de la encapsulación? ¿Por qué debemos mantener miembros privados así? Por razones prácticas, es así que los implementadores de nuestra API no pueden interrumpir la implementación al cambiar el estado (que debe ser administrado por la clase de propietario). Pero también, por razones de seguridad, son las inyecciones las que superan a nuestros estados miembros y evitan la validación y el control de clase. Entonces, cualquier cosa (marcos de trabajo o marcos de COI) que de alguna manera inyecta código antes de compilar para permitir el acceso externo a miembros privados es bastante enorme.
- Principio de responsabilidad única . En la superficie, los contenedores de COI parecen hacer las cosas más limpias. Pero imagine cómo lograría lo mismo sin los marcos auxiliares. Tendría constructores con una docena de dependencias que se pasan. Eso no significa que lo cubra con IOC Containers, ¡es algo bueno! Es una señal para refactorizar su código y seguir SRP.
Abierto / Cerrado . Al igual que SRP no es solo de clase (aplico SRP a líneas de responsabilidad única, y mucho menos a métodos). Abierto / Cerrado no es solo una teoría de alto nivel para no alterar el código de una clase. Es una práctica comprender la configuración de su programa y tener control sobre lo que se altera y lo que se extiende. Los contenedores IOC pueden cambiar la forma en que sus clases funcionan completamente en parte porque:
a. El código principal no está haciendo la determinación de cambiar las dependencias, sino la configuración del marco.
si. El alcance podría modificarse en un momento que no está controlado por los miembros llamantes, sino que está determinado externamente por un marco estático.
Entonces, la configuración de la clase no está realmente cerrada, sino que se altera en función de la configuración de una herramienta de terceros.
La razón por la que esta es una pregunta es porque no soy necesariamente un maestro de todos los contenedores de COI. Y si bien la idea de un contenedor COI es agradable, parecen ser solo una fachada que cubre una implementación deficiente. Pero para lograr un control de alcance externo, acceso de miembros privados y carga diferida, deben continuar muchas cosas cuestionables no triviales. AOP es excelente, pero la forma en que se logra a través de contenedores COI también es cuestionable.
Puedo confiar en C # y .NET GC para hacer lo que espero. Pero no puedo confiar en la misma herramienta de terceros que está alterando mi código compilado para realizar soluciones a cosas que no podría hacer manualmente.
Por ejemplo: Entity Framework y otros ORM crean objetos fuertemente tipados y los asignan a entidades de base de datos, además de proporcionar la funcionalidad básica de placa de caldera para realizar CRUD. Cualquiera podría construir su propio ORM y continuar siguiendo los Principios OOP / SOLID manualmente. Pero esos marcos nos ayudan a no tener que reinventar la rueda cada vez. Mientras que los Contenedores COI, al parecer, nos ayudan a trabajar deliberadamente en torno a los Principios OOP / SOLID y encubrirlo.
IOC
yExplicitness of code
es exactamente con lo que tengo problemas. La DI manual puede convertirse fácilmente en una tarea, pero al menos coloca el flujo de programa explícito autocontenido en un solo lugar: "Obtienes lo que ves, ves lo que obtienes". Si bien los enlaces y las declaraciones de los contenedores IOC pueden convertirse fácilmente en un programa paralelo oculto por sí solo.