Pregunta

¿Qué ventajas y desventajas tiene el uso de Enterprise Library Unity en comparación con otros contenedores IoC (Windsor, Spring.Net, Autofac ...)?

¿Fue útil?

Solución

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 IOC). Puede consultar la solución aquí (VS2008)

Como tales, 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 lo único que quiero que haga una IOC es crear y recuperar objetos para mí)

Nota: las diferencias entre las diferentes bibliotecas de recuperación de objetos pueden ser negadas usando CommonServiceLocator: http: // www. codeplex.com/CommonServiceLocator

Eso nos deja con la inicialización, que se realiza de dos formas: a través del código o mediante la configuración XML (app.config / web.config / custom.config). Algunos apoyan ambos, algunos apoyan solo uno. Debo tener en cuenta: algunos atributos de uso para ayudar a la IoC a lo largo.

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

StructureMap

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

Unity

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

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

Spring.NET

XML sólo lo más cerca que puedo decir. Pero para la funcionalidad, Spring.Net hace todo lo que puede hacer una IoC. Pero debido a que la única forma de unificar es a través de XML, generalmente se evita en las tiendas .net. 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á lo que usted quiera. Windsor es probablemente uno de los contenedores IoC más populares que existen.

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 tanto XML como código (con v1.2). Biblioteca de IoC simple agradable. Parece hacer lo básico sin mucho alboroto. Admite contenedores anidados con ámbito local de componentes y una gestión de la vida bien definida.

Así es como 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 la mejor compatibilidad con las funciones de lenguaje C # 3.0 y la mayor flexibilidad en la inicialización.

Nota : Chris Brandsma convirtió su respuesta original en entrada de blog .

Otros consejos

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

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

Habiendo dicho eso, es posible que desee mira esto .

Tema 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 miras la sección "Módulos" en la documentación, el contenedor DI es la base de la enorme cantidad de cosas que hace.

Corríjame si me equivoco, pero creo que Autofac admite la configuración XML como se indica en este enlace: Configuración XML de Autofac

Spring tiene una característica que puede inyectar parámetros al constructor o la propiedad según el nombre o la posición del parámetro. Esto es muy útil si el parámetro o la propiedad es un tipo simple (por ejemplo, un entero, un booleano). Consulte 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 en configuración. (corríjame si me equivoco, simplemente voy a través de 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, como no tengo experiencia con otros contenedores de IoC, no puedo saber si eso es válido.

Solo para agregar mis 2 centavos, he probado StructureMap y Unity. Descubrí que StructureMap está mal documentado / mal orientado, un dolor en el extremo para configurar y torpe para usar. Del mismo modo, no parece admitir escenarios como los reemplazos de argumentos de constructores en el momento de la resolución, que fue un punto de uso clave para mí. Así que lo dejé y me fui con Unity, y lo hice haciendo lo que quería en unos 20 minutos.

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 es que tiene un gran "error". Eso hace que se tiren constantemente las excepciones. Puede ignorar las excepciones durante la depuración. Sin embargo, ralentiza su aplicación tremendamente si la ejecuta, ya que lanzar una excepción es una operación costosa. Por ejemplo, actualmente estoy " arreglando " esta excepción en un lugar de mi código donde las excepciones de Unity agregan un 4 segundos extra al tiempo de procesamiento de una página. Para obtener más detalles y una solución alternativa, consulte:

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top