c# .net inversion-of-control unity-container enterprise-library
Puede ver la solución aquí (VS2008)

c# - Enterprise Library Unity vs Other IoC Containers



.net inversion-of-control (8)

¿Qué ventajas y desventajas tiene utilizar Enterprise Library Unity frente a otros contenedores IoC (Windsor, Spring.Net, Autofac ..)?



Estoy preparando una presentación para un grupo de usuarios. Como tal, simplemente revisé un montón de ellos. A saber: AutoFac, MEF, Ninject, Spring.Net, StructureMap, Unity y Windsor.

Quería mostrar el caso del 90% (inyección de constructor, que es principalmente de lo que las personas usan un COI de todos modos). Puede ver la solución aquí (VS2008)

Como tal, hay algunas diferencias clave:

  • Inicialización
  • Recuperación de objetos

Cada uno de ellos tiene también otras características (algunos tienen AOP y mejores artilugios, pero en general lo único que quiero que haga un IOC es crear y recuperar objetos para mí)

Nota: las diferencias entre la recuperación de objetos de diferentes bibliotecas se pueden negar utilizando el CommonServiceLocator: http://www.codeplex.com/CommonServiceLocator

Eso nos deja con la inicialización, que se realiza de dos maneras: a través de código o a través de la configuración XML (app.config / web.config / custom.config). Algunos admiten ambos, algunos admiten solo uno. Debo señalar: algunos atributos de uso para ayudar al IoC a lo largo.

Así que aquí está mi evaluación de las diferencias:

Ninject

Inicialización de código solamente (con atributos). Espero que te gusten las lambdas. El código de inicialización se ve así:

IKernel kernel = new StandardKernel( new InlineModule( x => x.Bind<ICustomerRepository>().To<CustomerRepository>(), x => x.Bind<ICustomerService>().To<CustomerService>(), x => x.Bind<Form1>().ToSelf() ));

StructureMap

Código de inicialización o XML o Atributos. v2.5 también es muy lambda''y. En general, este es uno de mis favoritos. Algunas ideas muy interesantes sobre cómo StructureMap utiliza atributos.

ObjectFactory.Initialize(x => { x.UseDefaultStructureMapConfigFile = false; x.ForRequestedType<ICustomerRepository>() .TheDefaultIsConcreteType<CustomerRepository>() .CacheBy(InstanceScope.Singleton); x.ForRequestedType<ICustomerService>() .TheDefaultIsConcreteType<CustomerService>() .CacheBy(InstanceScope.Singleton); x.ForConcreteType<Form1>(); });

Unity

Código de inicialización y XML. Buena biblioteca, pero la configuración de XML es un dolor en el trasero. Gran biblioteca para Microsoft o las tiendas de autopistas. La inicialización de código es fácil:

container.RegisterType<ICustomerRepository, CustomerRepository>() .RegisterType<ICustomerService, CustomerService>();

Spring.NET

XML solo lo más cerca que puedo decir. Pero para la funcionalidad, Spring.Net hace todo lo que un IoC puede hacer bajo el sol. Pero debido a que la única forma de unificar es a través de XML, generalmente las tiendas .net lo evitan. Aunque, muchas tiendas .net / Java usan Spring.Net debido a la similitud entre la versión .net de Spring.Net y el proyecto Java Spring.

Nota : La configuración en el código ahora es posible con la introducción de Spring.NET CodeConfig .

Windsor

XML y código. Al igual que Spring.Net, Windsor hará todo lo que pueda desear que haga. Windsor es probablemente uno de los contenedores de IoC más populares.

IWindsorContainer container = new WindsorContainer(); container.AddComponentWithLifestyle<ICustomerRepository, CustomerRepository>("CustomerRepository", LifestyleType.Singleton); container.AddComponentWithLifestyle<ICustomerService, CustomerService>("CustomerService",LifestyleType.Singleton); container.AddComponent<Form1>("Form1");

Autofac

Puede mezclar XML y código (con v1.2). Una buena biblioteca de IoC. Parece hacer lo básico sin mucho alboroto. Admite contenedores anidados con un alcance local de componentes y una administración de tiempo de vida bien definida.

Aquí es cómo lo inicializas:

var builder = new ContainerBuilder(); builder.Register<CustomerRepository>() .As<ICustomerRepository>() .ContainerScoped(); builder.Register<CustomerService>() .As<ICustomerService>() .ContainerScoped(); builder.Register<Form1>();

Si tuviera que elegir hoy: probablemente iría con StructureMap. Tiene el mejor soporte para las características del lenguaje C # 3.0 y la mayor flexibilidad en la inicialización.

Nota : Chris Brandsma convirtió su respuesta original en una publicación de blog .


Por lo que he visto, son prácticamente iguales, excepto por algunos detalles de implementación aquí y allá. La mayor ventaja que Unity tiene sobre la competencia es que la proporciona Microsoft, hay muchas compañías que temen a OSS.

Una desventaja es que es bastante nuevo, por lo que podría tener errores que los antiguos jugadores ya hayan solucionado.

Habiendo dicho eso, es posible que desee verificar esto .


Solo para agregar mis 2 centavos, he intentado tanto StructureMap como Unity. Encontré que StructureMap está mal documentada / equivocadamente documentada, un problema en la configuración y poco fácil de usar. Del mismo modo, no parece ser compatible con escenarios como el argumento de constructor que reemplaza el tiempo de resolución, que fue un punto clave de uso para mí. Así que lo dejé y me fui con Unity, y lo hice hacer lo que quería en unos 20 minutos.


Spring tiene una característica que puede inyectar parámetros al constructor o a la propiedad en función del nombre o posición del parámetro. Esto es muy útil si el parámetro o propiedad es un tipo simple (por ejemplo, un entero, un booleano). Vea el ejemplo aquí . No creo que esto realmente compensa la incapacidad de Spring para hacer config en el código.

Windsor también puede hacer esto, y puede hacerlo en código no config. (corrígeme si me equivoco, solo voy por lo que he escuchado aquí).

Me gustaría saber si la Unidad puede hacer esto.


Una cosa a tener en cuenta: Ninject es el único contenedor de IoC que admite inyecciones de dependencia contextual (según su sitio web). Sin embargo, como no tengo experiencia con otros contenedores de IoC, no puedo decir si eso es válido.


Viejo hilo, pero ya que esto es lo primero que Google me mostró cuando escribí unity vs spring.net ...

Spring hace CodeConfig ahora si no te gusta la configuración XML

http://www.springframework.net/codeconfig/doc-latest/reference/html/

Además, Spring es mucho más que solo un contenedor DI, si miras la sección ''Módulos'' en los documentos, el contenedor DI es la base de la gran cantidad de cosas que hace.


Yo personalmente uso Unity, pero solo porque es de Microsoft. Lamento la decisión por una razón: lo más grande que tiene contra ella tiene un gran "error" que hace que constantemente arroje excepciones. Puede ignorar las excepciones durante la depuración. Sin embargo, ralentiza enormemente tu aplicación si te topas con ella, ya que lanzar una excepción es una operación costosa. Por ejemplo, actualmente estoy "arreglando" esta excepción en un punto de mi código donde las excepciones de Unity agregan 4 segundos adicionales al tiempo de renderizado de una página. Para obtener más detalles y una solución alternativa, consulte:

¿Se puede hacer que Unity no arroje SynchronizationLockException todo el tiempo?