119

He estado leyendo los artículos en MSDN sobre Unity (Dependency Injection, Inversion of Control), pero creo que lo necesito explicado en términos simples (o ejemplos simples). Estoy familiarizado con el patrón de MVPC (lo usamos aquí), pero aún no puedo captar esta unidad, y creo que es el siguiente paso en el diseño de nuestra aplicación.¿Alguien puede explicar Microsoft Unity?

+4

Me encanta cómo tiene el mismo nombre que "Unity", así que cuando estoy buscando Unity Game Engine veo esta tecnología antigua, suspiro. Todos los nombres de la buena banda están tomados, supongo. –

Respuesta

139

Unity es solo un "contenedor" de IoC. Google StructureMap y pruébelo en su lugar. Me parece un poco más fácil de asimilar, cuando las cosas de IoC son nuevas para ti.

Básicamente, si entiendes IoC entiendes que lo que estás haciendo es invertir el control para cuando se crea un objeto.

Sin Ioc:

public class MyClass 
{ 
    IMyService _myService; 

    public MyClass() 
    { 
     _myService = new SomeConcreteService();  
    } 
} 

Con contenedor IoC:

public class MyClass 
{ 
    IMyService _myService; 

    public MyClass(IMyService myService) 
    { 
     _myService = myService;  
    } 
} 

Sin COI, su clase que se basa en la IMyService tiene que nuevo en marcha una versión concreta del servicio a utilizar. Y eso es malo por varias razones (ha acoplado su clase a una versión concreta concreta de IMyService, no puede probarla en una unidad fácilmente, no puede cambiarla fácilmente, etc.)

Con un contenedor IoC que "configura" el contenedor para resolver esas dependencias por usted. Entonces, con un esquema de inyección basado en el constructor, simplemente pasa la interfaz a la dependencia IMyService en el constructor. Cuando crea MyClass con su contenedor, su contenedor resolverá la dependencia de IMyService por usted.

Usando StructureMap, configurar el contenedor se ve así: "Cuando alguien pide al IMyService, darles una copia del SomeConcreteService"

StructureMapConfiguration.ForRequestedType<MyClass>().TheDefaultIsConcreteType<MyClass>(); 
StructureMapConfiguration.ForRequestedType<IMyService>().TheDefaultIsConcreteType<SomeConcreteService>(); 

Así que lo que ha hecho es decirle al contenedor, Y también ha especificado que cuando alguien solicita una MyClass, obtiene una MyClass concreta.

Eso es todo lo que hace un contenedor IoC. Pueden hacer más, pero ese es el objetivo: resuelven las dependencias por usted, por lo que no tiene que hacerlo (y no tiene que usar la palabra clave "nueva" en todo su código).

paso final: al crear su MiClase, se podría hacer esto:

var myClass = ObjectFactory.GetInstance<MyClass>(); 

Espero que ayude. No dude en enviarme un correo electrónico.

+2

Entonces, ¿es como una fábrica, supongo?Si sigo esto correctamente, ¿no usaría en lugar de en el último ejemplo? entonces sería var myClass = ObjectFactory.GetInstance ()? Gracias por su ayuda, ¡este es un buen comienzo para mí! –

+3

En cierto modo, es como una fábrica, sí. Una fábrica maestra para su aplicación. Pero se puede configurar para devolver muchos tipos diferentes, incluidos los singletons. En cuanto a la interfaz de MyClass, si se trata de un objeto comercial, no extraería una interfaz. Para todo lo demás, generalmente lo haría. –

+0

qué ocurre si solo llamas a ObjectFactory.GetInstance (); y no configuró la SomeConcreteClass? ¿Recibirías un error en ese caso? – RayLoveless

27

Unity es una biblioteca como muchas otras que le permite obtener una instancia de un tipo solicitado sin tener que crearlo usted mismo. Así que dado.

public interface ICalculator 
{ 
    void Add(int a, int b); 
} 

public class Calculator : ICalculator 
{ 
    public void Add(int a, int b) 
    { 
     return a + b; 
    } 
} 

Se podría utilizar una biblioteca como la Unidad para registrar la calculadora para ser devueltos cuando se solicita la ICalculator tipo conocido como IoC (Inversión de Control) (este ejemplo es teórico, no es técnicamente correcto).

IoCLlibrary.Register<ICalculator>.Return<Calculator>(); 

Así que ahora cuando se desea una instancia de un ICalculator que acaba ...

Calculator calc = IoCLibrary.Resolve<ICalculator>(); 

bibliotecas IoC por lo general se pueden configurar para un producto único, o bien mantener o crear una nueva instancia cada vez que resuelven una tipo.

Ahora vamos a decir que tiene una clase que se basa en un ICalculator estar presente usted podría tener ..

public class BankingSystem 
{ 
    public BankingSystem(ICalculator calc) 
    { 
     _calc = calc; 
    } 

    private ICalculator _calc; 
} 

Y se puede configurar la biblioteca para inyectar un objeto al constructor cuando se crea.

Por lo tanto, DI o Inyección de Dependencia significa inyectar cualquier objeto que otro pueda requerir.

8

Unity es un IoC. El objetivo de IoC es abstraer el cableado de las dependencias entre tipos fuera de los tipos mismos. Esto tiene un par de ventajas. En primer lugar, se realiza de forma centralizada, lo que significa que no es necesario cambiar una gran cantidad de código cuando cambian las dependencias (lo que puede ser el caso de las pruebas unitarias).

Además, si el cableado se realiza utilizando datos de configuración en lugar de código, en realidad puede reconectar las dependencias después de la implementación y así cambiar el comportamiento de la aplicación sin cambiar el código.

35

Acabo de ver los 30 minutos Unity Dependency Injection IoC Screencast de David Hayden y sentí que era una buena explicación con ejemplos. Aquí hay un fragmento de las notas de espectáculo:

El screencast muestra varios usos comunes del COI Unidad, tales como:

  • Creación de tipos no en el envase
  • Registro y TypeMappings Resolución de
  • Registro y Resolución de asignaciones de tipos con nombre
  • Singletons, LifetimeManagers y ContainerControlledLifetimeManager
  • Registro de instancias existentes
  • Dependencias inyectar en instancias existentes
  • Rellenar la UnityContainer través App.config/Web.config
  • Especificación de Dependencias través de la API de inyección en oposición a la dependencia Atributos
  • Usando Nested (padre-hijo) Contenedores
4

MSDN tiene un Developer's Guide to Dependency Injection Using Unity que puede ser útil.

La Guía del desarrollador comienza con los principios básicos de la inyección de dependencia y continúa con ejemplos de cómo usar Unity para la inyección de dependencias. A partir de febrero de 2014, la Guía del desarrollador cubre Unity 3.0, que se lanzó en abril de 2013.

Cuestiones relacionadas