¿Qué herramienta de dependency injection debo usar?

Estoy pensando en usar Microsoft Unity para mi herramienta Dependency Injection en nuestra interfaz de usuario.

Nuestro Nivel Medio ya usa Castle Windsor, pero estoy pensando que debería quedarme con Microsoft.

¿Alguien tiene alguna idea sobre cuál es la mejor herramienta de Inyección de Dependencia?

  • Autofac
  • Castle MicroKernel / Windsor
  • PicoContainer.NET
  • Puzzle.NFactory
  • Spring.NET
  • StructureMap
  • Ninject
  • Unidad
  • Inyector simple
  • NauckIT.MicroKernel
  • WINTER4NET
  • ObjectBuilder

Apegarse a un contenedor no es realmente importante, si su sistema ha sido diseñado teniendo en cuenta el IoC / DI. Con el enfoque adecuado, puede cambiar fácilmente la biblioteca IoC más adelante.

Y, por supuesto, el contenedor debe proporcionar suficiente flexibilidad para admitir escenarios comunes ampliamente utilizados (gestión del ciclo de vida, anidamiento adecuado de contenedores, configuración de código y XML, interceptación, resolución rápida).

Recomiendo elegir entre Castle (ampliamente utilizado y tener muchas bibliotecas de integración) y Autofac (ligero, rápido y con un nested de contenedor adecuado, pero no es muy utilizado)

Hay una lista completa de contenedores de IoC por Hanselman

PD: No quieres usar Unity

Habiendo agregado recientemente el uso de 6 de estos ( Windsor , Unity , Spring.Net , Autofac , Ninject , StructureMap ) puedo ofrecer un resumen rápido de cada uno de ellos, nuestros criterios de selección y nuestra elección final.

Nota: no miramos a PicoContainer.Net ya que uno de los miembros de nuestro equipo consideró que el puerto .Net era bastante pobre con respecto a la versión de Java. Tampoco miramos a ObjectBuilder, ya que Unity está construido sobre ObjectBuilder2 y se consideró una opción superior por defecto.

En primer lugar, puedo decir que más o menos todos son bastante similares y realmente se reduce a lo que realmente funciona mejor para usted y sus requisitos específicos. Nuestros requisitos incluyen:

Requisitos

  • Inyección basada en el constructor (no se pretende usar la inyección de propiedad, campo o método)
  • Configuración progtwigble ( no XML)
  • jerarquías de contenedor (una por aplicación, por solicitud y por sesión para vincular de forma más implícita el scope de las vidas de los componentes al contenedor)
  • gestión de vida útil del componente (para un scope más granular, por ejemplo, transitorio / único)
  • inyección desde la interfaz al tipo o instancia concreta (por ejemplo, ILogger -> typeof(FileLogger) o ILogger -> new FileLogger() )
  • creación avanzada de componentes / “mecanismo de evento de creatona” para la inicialización previa / posterior
  • eliminación correcta de los componentes IDisposable en contenedor derribar
  • información bien documentada y / o en línea fácilmente disponible

    Nota: aunque el rendimiento era un requisito, no se tuvo en cuenta en la selección, ya que parecía que todos los contenedores revisados ​​eran similares según este punto de referencia.

Prueba

Cada contenedor se usó en un típico proyecto de formularios web Asp.Net (ya que este era nuestro tipo de aplicación de destino). Utilizamos una única página simple con un único control de usuario simple, heredando cada uno de una página base / control de base, respectivamente. Usamos 1 contenedor en la BasePage para un contenedor de scope “por solicitud” y 1 en el scope global.asax para un scope de “aplicación” e intentamos encadenarlos para que las dependencias pudieran resolverse desde ambos contenedores.

Cada aplicación web compartía un conjunto artificial de objetos de dominio que simulaban múltiples niveles de dependencia, tipo de ámbito (singleton / transitorio) y también de clases gestionadas y no gestionadas (se requiere IDisposable ). Los componentes de dependencia de “nivel superior” se inyectaron manualmente desde los métodos en la página BasePage .

Resultados

Windsor – Satisface todos los criterios y tiene un buen historial de casos, una comunidad de bloggers y documentación en línea. Fácil de usar y, probablemente, la elección de hecho. Creación avanzada de componentes a través de las instalaciones de fábrica. También se permite el encadenamiento de contenedores creados individualmente.

Spring.Net – Documentación detallada e inútil y no obvia / fácil para la configuración progtwigble. No fue compatible con los generics. No elegido

Ninject: fácil de usar con buena documentación clara. Potente conjunto de funciones que cumple todos nuestros requisitos, excepto las jerarquías de contenedores, por lo que lamentablemente no se eligió.

StructureMap: pobremente documentado, aunque tenía un conjunto de características bastante avanzado que cumplía con todos nuestros requisitos, sin embargo no había un mecanismo incorporado para las jerarquías de contenedores, aunque podría ser pirateado usando bucles para ver aquí La interfaz fluida de la expresión lambda parecía un poco pasada complicado al principio, aunque podría ser encapsulado de distancia.

Unidad – Bien documentada, fácil de usar y cumplió con todos nuestros criterios de selección y tiene un mecanismo de extensión fácil para agregar el mecanismo de creación de eventos de pre / post que necesitamos. Los contenedores secundarios deben crearse a partir de un contenedor principal.

Autofac: bien documentado y relativamente fácil de usar, aunque la configuración de la expresión lambda parece un poco complicada, sin embargo, una vez más, se puede encapsular fácilmente. El scope del componente se logra a través de un mecanismo de “etiquetado” y todos los componentes se configuran por adelantado usando un generador que era un poco inconveniente. Los contenedores secundarios se crearon a partir de un elemento primario y se les asignaron componentes desde una “etiqueta”. Inyección genérica permitida.

Conclusión

Nuestra elección final fue entre Windsor y Unity, y esta vez elegimos Unity debido a su facilidad de uso, documentación, sistema de extensión y estando en estado de “producción”.

Aquí hay un buen artículo que compara los contenedores de IOC de .NET. http://blog.ashmind.com/index.php/2008/08/19/comparing-net-di-ioc-frameworks-part-1/

Empecé a usar Autofac hace un año y no he vuelto a mirar desde …

Soy un fan de Autofac, pero tanto Windsor como Unity harán un buen trabajo (aunque Windsor es más capaz que la unidad y no requiere atribuir el código). Sin embargo, hay muchas buenas razones no técnicas para apegarse a un único contenedor en un sistema.

Usa lo que funciona La mayoría tienen características que son únicas para ellos, y casi todas son más ricas en funciones que Unity. Si la unidad es todo lo que necesitas, puedes usarla.

Usar la unidad de Microsoft solo porque es de Microsoft es una manera pobre de tomar una decisión. Piense en lo que necesita y por qué, y elija el que se ajuste a sus necesidades.

Sin embargo, secundo la idea de apegarse a un solo contenedor si es posible.

He estado usando el Marco de Extensibilidad Administrado y me ha resultado bastante fácil trabajar con él. Se ha integrado en .NET 4 .

A menos que ya tenga experiencia y una preferencia personal para una subtecnología particular utilizada por una de las posibles soluciones de contenedor IoC, todas funcionan bien y no veo a nadie en particular con una “función asesina” que lo destaque. de los otros. Unity es probablemente la mejor opción para las soluciones que ya utilizan P & P Enterprise Library 4.x …

IoC Container Benchmark: la comparación de rendimiento tiene tablas de comparación de rendimiento y características para más de 20 productos y los mantiene actualizados.

La conclusión del artículo:

SimpleInjector, Hiro, Funq, Munq y Dynamo ofrecen el mejor rendimiento, son extremadamente rápidos. Pruébalos!

Especialmente Simple Injector parece ser una buena opción. Es muy rápido, tiene una buena documentación y también admite escenarios avanzados como la interceptación y decoradores generics.