Enterprise Library Unity vs otros contenedores IoC [cerrado]

135

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

Yoann si
fuente
9
Este tipo de preguntas siempre están cerradas. Las opiniones son importantes. ¿Hay un lugar donde colocarlos?
Jeson Martajaya
1
@JesonMartajaya, quería recomendar exactamente el mismo comentario, es molesto que las preguntas se estén cerrando, pero no hay respuesta para una alternativa.
Mohammed Noureldin

Respuestas:

234

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:

  • Inicialización
  • Recuperación de objetos

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:

Ninject

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()
                    ));

EstructuraMapa

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>();
 });

Unidad

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>();

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. 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 .

Windsor

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");

Autofac

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 .

Chris Brandsma
fuente
1
Configuración Xml solamente, lo que hace que sea mucho más difícil de configurar. Básicamente, las únicas personas que veo que quieren usar Spring.Net son antiguos desarrolladores de Java.
Chris Brandsma
Chris, con respecto a tus conclusiones: ¿puedes dar más detalles sobre a) a qué características de C # 3 te refieres yb) a qué tipos de inicialización son importantes para ti? ¡Gracias!
Nicholas Blumhardt
2
Hola, Nicholas: en cuanto al soporte de C # 3, todo lo que Autofac ya hace. :) Para la inicialización, quiero un soporte sencillo para singletons / non singletons e inicialización por sesión. Finalmente, quiero formas fáciles de referenciar por nombre personalizado. (algo que es un PITA en StructureMap). La característica final que me gusta más ahora que cuando escribí esto originalmente: AutoMocking. No lo uso todo el tiempo, pero es muy agradable tener una ronda.
Chris Brandsma
También mencionaste MEF, yo uso MEF para entregar mis objetos de implementación de IRepository y encuentro que funciona bien. ¿Qué piensas sobre MEF?
terjetyl
Aquí hay un bonito screencast de 20 minutos que muestra la mayor parte de Unity: pnpguidance.net/Screencast/…
Pat
7

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 .

rodbv
fuente
4

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.

Ricardo
fuente
2

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.

Antonio
fuente
2

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.

ehsanullahjan
fuente
Si esto es todo "inyección de dependencia contextual" está en Ninject entonces ... uhh, nada especial. Compatible (por varios medios) en Unity, AutoFac, Windsor al menos.
user2864740
1

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.

Jacobs Data Solutions
fuente
1

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?

Josh Mouch
fuente
¡Gracias por la advertencia! Según esta respuesta de la pregunta a la que se refirió , el error ahora está resuelto.
Sam
¿Por qué está Unity lanzando una excepción? Por lo general, una excepción es un 'error crítico' (como la dependencia unreolveable) y no es algo que ser suprimida ..
user2864740
Disculpe, ¿está resuelto este "error" o ha encontrado la manera de evitarlo? Estoy eligiendo marco en C # .NET ahora y con ganas de saber si la unidad es tiempo-costo todavía ...
Jog Dan