2009-11-11 13 views

Respuesta

15

Inversión de Control

una suma rápida (mucho más la lectura está disponible este tema, y ​​le recomiendo leer más) ...

Unity de Microsoft del equipo Enterprise Patterns and Practices es un proyecto de contenedor de inversión de control, o IoC para abreviar. Al igual que Castle Windsor, StructureMap, etc. Este tipo de desarrollo también se menciona en los términos de Lamen como un acoplamiento flexible de sus componentes.

IoC incluye un patrón para Inyección de Dependencia de sus objetos, en el que confía en un componente externo para cablear las dependencias dentro de sus objetos.

Por ejemplo, en lugar de acceder a los administradores estáticos (que son casi imposibles de probar por unidad), crea un objeto que depende de una dependencia externa para actuar. Tomemos un servicio de publicación en el que desee acceder al DB para obtener una publicación.

public class PostService : IPostService 
{ 
    private IPostRepository _postRepo; 

    public PostService(IPostRepository postRepo) 
    { 
    _postRepo = postRepo; 
    } 

    public IList<Post> GetPosts() 
    { 
    return _postRepo.GetAllPosts().ToList(); 
    } 
} 

Este objeto PostService ahora tiene una dependencia externa en IPostRepository. ¿Observe cómo no se usan clases de concretos y no de gestores estáticos?En su lugar, tiene flojo acoplamiento de una Interfaz simple, que le da el poder de cablear todos los diferentes tipos de clases concretas que implementan IPostRepository.

El propósito de Microsoft Unity es conectar ese IPostRepository por usted automáticamente. Para que nunca tenga que preocuparse por hacer:

// you never have to do this with Unity 
IPostRepository repo = new PostRepository(); 
IPostService service = new PostService(repo); // dependency injection 
IList<Post> posts = service.GetPosts(); 

Lo anterior muestra donde se tiene que implementar dos clases concretas, PostRepository() y PostService(). Eso está estrechamente relacionado con su aplicación para exigir/exigir esas instancias exactas, y deja muy difícil la prueba unitaria.

su lugar, se utiliza la unidad en su punto final (El controlador de MVC, o código atrás en las páginas ASPX):

IUnityContainer ioc = new UnityContainer(); 
IPostService postService = ioc.Resolve<IPostService>(); 
IList<Post> posts = postService.GetPosts(); 

en cuenta que no hay hormigones utilizados en este ejemplo (excepto UnityContainer y Post , obviamente)! No hay nada concreto de los servicios, ni repositorio. Eso es poco flexible en su máxima expresión.

Aquí está el golpeador verdadero ...

Unidad (o cualquier infraestructura de contenedores IoC por ahí!) Inspeccionará IPostService en busca de dependencias. Verá que quiere (depende) de una instancia de IPostRepository. Por lo tanto, Unity irá a su mapa de objetos y buscará el primer objeto que implemente el IPostRepository que se registró con el contenedor y lo devolverá (es decir, una instancia de SqlPostRepository). Ese es el poder real detrás de los marcos de la IoC: el poder de inspeccionar los servicios y cablear cualquiera de las dependencias automáticamente.

Tengo que terminar mi publicación sobre las comparaciones de UNity vs Castle vs StructureMap. En realidad prefiero Castle Windsor debido a sus opciones de archivo de configuración y puntos de extensibilidad personalmente.

+1

+1 - buena respuesta! Uso y me gusta la Unidad. – TrueWill

+1

+1 - ¡buena respuesta! –

+0

Gracias chicos. A lo largo de los años (guau, 2 años desde que publiqué esta respuesta), en realidad comencé a alejarme de Castle Windsor debido a que es "Si llamas a Resolver (), debes llamar a Release (Object)" inherit "No es un error , pero una característica "problema". Eso ha causado una serie de pérdidas de memoria en las aplicaciones que he escrito. En su lugar, me estoy moviendo al MEF con un manejo Contextual personalizado de las Requerimientos Web. – eduncan911

4

El bloque de aplicaciones de Unity se utiliza para dependency injection. Creo que la mejor definición simple para DI es de this question

Cuando va a sacar cosas del refrigerador, puede causar problemas. Podrías dejar la puerta abierta, podrías obtener algo que mamá o papá no quieren que tengas. Incluso podría estar buscando algo que ni siquiera tenemos o que ha expirado.

Lo que debe hacer es indicar la necesidad, "Necesito algo para beber con el almuerzo", y luego nos aseguraremos de que tenga algo cuando se siente a comer.

Así, por ejemplo,

IUnityContainer container = new UnityContainer(); 
ILunch lunch = container.Resolve<ILunch>(); 
Console.WriteLine(lunch.Drink); 

Este salidas "Limonada" porque definimos Drink como dependencia.

public class ILunch { 
    [Dependency] 
    public IDrink Drink { get; set; } 
} 

En lo que va practicidad, la inyección de dependencia es realmente grande cuando dependen de otros objetos y no desea que el desarrollador tenga que hacerlo manualmente. Es así de simple. También es genial para burlarse. El ejemplo más usado que puedo pensar que uso es burlarse de una capa de datos. A veces la base de datos no está lista, así que en lugar de detener el desarrollo, tengo una capa falsa que devuelve datos falsos. El objeto de datos se accede a través de DI y se puede configurar para devolver objetos que acceden a la capa falsa o a la capa real. En este ejemplo, casi estoy usando el DI Container como una clase de fábrica configurable. Para obtener más información sobre Unity, MSDN tiene algunos recursos excelentes http://msdn.microsoft.com/en-us/library/cc468366.aspx.

Otros buenos marcos de DI incluyen Spring.NET y Ninject

Cuestiones relacionadas