unity ioc inversiones injection framework explicacion dependency definicion control container c# inversion-of-control

c# - inversiones - Ejemplos de Contenedores IoC



unity ioc (9)

¿Alguien tiene buenos ejemplos de contenedores IoC (preferiblemente en c #) y cómo y por qué usarlos? He revisado la página wiki y Ayende''s ejemplo Ayende''s , pero todavía no entiendo el concepto.

¿Y cuándo y dónde debo usar un contenedor IoC?


¿Estás tratando de construir un contenedor de IoC? ¿Por qué no utilizar uno de los disponibles como Spring.NET, StructureMap o Unity Application Block? Here hay una lista de proyectos IoC de código abierto.


Echa un vistazo a Spring IoC (.net) un contenedor java / .net. La documentación es bastante buena introducción.

En un breve resumen: puede pensar en IoC como una arquitectura que fomenta: la composición y programación de objetos a una interfaz .

Esto te da lo siguiente:

  • la capacidad de probar su código fácilmente (puede probar fácilmente sus objetos aislándose burlándose de todas sus dependencias).

  • Una configuración extremadamente avanzada (porque su programa con IoC es solo un conjunto de objetos y una configuración que une los objetos).

  • La capacidad de extender o modificar la aplicación compilada de bytes (esto es cierto para Java, no estoy seguro de que sea cierto para .net).


Estoy usando Unity para mi contenedor IoC, pero la diferencia entre los contenedores reside en más de lo que puedes hacer con DI.

DI (inyección de dependencia) es principalmente una forma de obtener un acoplamiento más suelto entre partes dispares de su programa. Entonces, si escribiste un juego que te guste cómo funciona, al usar DI puedes cambiar los personajes o el motor de física en el juego sin cambiar otras partes del juego, entonces, si alguien paga más dinero, obtiene el motor más realista. o los mejores personajes, pero como nada más está cambiando, la prueba es más simple.

La prueba de unidades también es más fácil con DI, ya que puede simularse en la base de datos, por ejemplo, simplemente cambiando la implementación que utilizará la aplicación, sin afectar a nada más.

Si usa Spring.NET, por ejemplo, tendrá acceso a un marco muy poderoso, pero puede hacer una gran cantidad de cosas que no usará, así que busque algo más pequeño. Creo que la mejor regla es encontrar la implementación más pequeña y sencilla que satisfaga sus necesidades y utilizarla.


He usado StructureMap bastante. El resto de tu pregunta está bastante cargada. Intentaré explicar el concepto en un ejemplo.

Supongamos que ha creado un sitio web que aceptará pagos a través de PayPal. PayPal es ahora una dependencia. Pero no desea codificar contra un proveedor específico de PayPal.

En su lugar, crearías y codificarías contra una interfaz como esta:

interface IPaymentProcessor { bool ProcessPayment(amount, ....); }

Todo su código de PayPal residiría en una clase que implementa los métodos de su interfaz: PayPalPaymentProcessor , por ejemplo.

Ahora tiene un objeto que realmente utilizará para procesar los pagos. Esto podría ser un Controlador (ASP.NET-MVC, ViewModel-WPF) o simplemente una clase como se muestra aquí:

class PaymentProcessor { private IPaymentProcessor _processor = null; public PaymentProcessor(IPaymentProcessor processor) { _processor = processor; } public bool ProcessTransaction(Transaction trans) { _processor.ProcessPayment(trans.amount, ...); } }

Aquí es donde entra un contenedor IoC. En lugar de que usted llame al constructor manualmente, permitiría que un contenedor IoC inyecte la dependencia:

PaymentProcessor processor = ObjectFactory.GetInstance<PaymentProcessor>();

Esta pieza de código le dice a StructureMap "Cada vez que vea un constructor que necesita un IPaymentProcessor , devuelva un nuevo PayPalPaymentProcessor ".

ObjectFactory.Initialize(x => { x.ForRequestedType<IPaymentProcessor>().TheDefaultIsConcreteType<PayPalPaymentProcessor>(); });

Toda esta asignación es independiente de su código de implementación y puede cambiarlos en un momento posterior con poca refactorización. Hay mucho más en los contenedores IoC, pero ese es el concepto básico. Puede automatizar la inyección de constructores para evitar las llamadas directamente a ObjectFactory .

¡Espero que esto ayude!



Normalmente uso StructureMap , principalmente porque estoy familiarizado con la sintaxis. También escuché cosas buenas sobre autofac y estoy deseando probar Ninject cuando Ninject a v2.

Es posible que desee ver esta respuesta cuando hablo sobre el uso básico de un contenedor de IoC (siempre creo que las cosas son más fáciles de entender con un simple ejemplo), lo que podría ayudarlo a comprender un poco más las cosas. Básicamente, el contenedor IoC lo ayuda a construir objetos con todas las dependencias satisfechas y le permite cambiar sus dependencias con un código de configuración mínimo.


Si desea ver un contenedor IoC bajo el capó y también el punto (Dependency Injection), hay un gran podcast en DNR TV ( Episodio 126 ) que realmente explica en detalle cómo crearlos, por qué los necesita. Es un podcast realmente maravilloso. Una vez que haya visto este video, podrá ver Unity , Ninject , StructureMap , etc. y entender lo que están haciendo.


Tenga en cuenta las siguientes limitaciones del contenedor IOC. Tengo que advertir a la gente, porque estoy viviendo con el infierno de tener que soportar un sistema que lo use:

  • Las excepciones lanzadas por los constructores son tragadas. Solo se obtiene la excepción "no se pudo crear dependencia". Eso significa que no puede capturar las excepciones esperadas si se lanza en un constructor.
  • No se puede pasar por los constructores.
  • Olvidarse de registrar una interfaz se rompe en tiempo de ejecución en lugar de compilar.
  • Todas sus clases solo pueden tener un constructor y todas tienen que aceptar interfaces como parámetros.
  • Todas las dependencias están instanciadas, por lo que no puede compartir instancias, lo que significa que el uso de la memoria puede aumentar rápidamente.
  • Promueve muchas interdepencias que pueden ocultar el hecho de que tu código se haya convertido en espagueti. Facilitar la instalación de todas estas interdepencias solo enmascara que existe un problema subyacente potencial.
  • No puede administrar su propia "Unidad de trabajo" muy fácilmente porque no puede administrar una transacción a través de múltiples dependencias ya que no tenía el control de crear instancias y pasar en el contexto de esa transacción.

No me malinterprete, me encanta la inyección de dependencia y el principio de inversión de control, pero creo que el contenedor IOC se puede usar de manera responsable, pero tenga en cuenta las batallas que tendrá que luchar debido a la lista anterior.


Usamos Ninject debido a su API simple y resolución rápida de objetos. Está muy bien documentado y aprovecha las características de C # 3.0 como las expresiones lambda para facilitar la especificación.

Puedes encontrar varios screencast en Ninject here