¿Qué ventajas y desventajas tiene usar Enterprise Library Unity frente a otros contenedores IoC (Windsor, Spring.Net, Autofac ..)?
¿Qué ventajas y desventajas tiene usar Enterprise Library Unity frente a otros contenedores IoC (Windsor, Spring.Net, Autofac ..)?
Respuestas:
Estoy preparando una presentación para un grupo de usuarios. Como tal, acabo de pasar por 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 para lo que la gente usa un COI de todos modos). Puede consultar la solución aquí (VS2008)
Como tal, hay algunas diferencias clave:
Cada uno de ellos también tiene otras características (algunos tienen AOP y mejores artilugios, pero en general todo lo que quiero que haga un COI es crear y recuperar objetos para mí)
Nota: las diferencias entre las diferentes bibliotecas de recuperación de objetos se pueden negar utilizando CommonServiceLocator: http://www.codeplex.com/CommonServiceLocator
Eso nos deja con la inicialización, que se realiza de dos maneras: mediante código o mediante configuración XML (app.config / web.config / custom.config). Algunos admiten ambos, algunos admiten solo uno. Debo señalar: algunos usan atributos para ayudar a la IoC.
Así que aquí está mi evaluación de las diferencias:
Solo inicialización de código (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()
));
Código de inicialización o XML o Atributos. v2.5 también es muy lambda'y. Con todo, este es uno de mis favoritos. Algunas ideas muy interesantes sobre cómo StructureMap usa los 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>();
});
Código de inicialización y XML. Buena biblioteca, pero la configuración XML es un fastidio. Gran biblioteca para Microsoft o las tiendas de la autopista. La inicialización del código es fácil:
container.RegisterType<ICustomerRepository, CustomerRepository>()
.RegisterType<ICustomerService, CustomerService>();
XML solo lo más cerca que puedo decir. Pero para la funcionalidad Spring.Net hace todo lo que un IoC puede hacer. Pero debido a que la única forma de unificar es a través de XML, generalmente es evitado por las tiendas .net. Sin embargo, 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 .
XML y código. Al igual que Spring.Net, Windsor hará todo lo que quieras 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");
Puede mezclar XML y código (con v1.2). Bonita biblioteca simple de IoC. Parece hacer lo básico sin mucho alboroto. Admite contenedores anidados con alcance local de componentes y una gestión del tiempo de vida bien definida.
Así es como lo inicializa:
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 .
Hasta donde he visto, son más o menos lo mismo, excepto por algunos detalles de implementación aquí y allá. La mayor ventaja que tiene Unity sobre la competencia es que es proporcionada por Microsoft, hay muchas compañías que temen el OSS.
Una desventaja es que es bastante nuevo, por lo que puede tener errores que los jugadores mayores ya han resuelto.
Dicho esto, es posible que desee ver esto .
Hilo antiguo, pero como 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 un simple contenedor DI, si nos fijamos en la sección 'Módulos' en los documentos, el contenedor DI es la base de la gran cantidad de cosas que hace.
Corríjame si me equivoco, pero creo que Autofac admite la configuración XML como se detalla en este enlace: Configuración XML de Autofac
Spring tiene una característica que puede inyectar parámetros al constructor o la propiedad en función del nombre o la posición del parámetro. Esto es muy útil si el parámetro o propiedad es de tipo simple (por ejemplo, un entero, un booleano). Vea el ejemplo aquí . No creo que esto realmente compense la incapacidad de Spring para hacer la configuración 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 Unity 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, debido a que no tengo experiencia con otros contenedores de IoC, no puedo decir si eso se cumple.
Solo para agregar mis 2 centavos, probé tanto StructureMap como Unity. Encontré que StructureMap estaba mal documentado / mal orientado, un dolor en el trasero para configurar y torpe para usar. Del mismo modo, no parece admitir escenarios como las anulaciones del argumento del constructor en el momento de la resolución, que fue un punto de uso clave para mí. Así que lo dejé caer y fui con Unity, y tuve que hacer lo que quería en unos 20 minutos.
Yo personalmente uso Unity, pero solo porque es de Microsoft. Lamento la decisión por una razón: lo más importante que tiene en contra tiene un gran "error" que hace que constantemente arroje excepciones. Puede ignorar las excepciones durante la depuración. Sin embargo, ralentiza enormemente su aplicación si la encuentra, 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 representación 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?