Quais são os prós e os contras do uso do Enterprise Library Unity versus outros contêineres IoC (Windsor, Spring.Net, Autofac ..)?
Quais são os prós e os contras do uso do Enterprise Library Unity versus outros contêineres IoC (Windsor, Spring.Net, Autofac ..)?
Respostas:
Estou preparando uma apresentação para um grupo de usuários. Como tal, eu apenas passei por um monte deles. Ou seja: AutoFac, MEF, Ninject, Spring.Net, StructureMap, Unity e Windsor.
Eu queria mostrar o caso de 90% (injeção de construtor, que é principalmente para o que as pessoas usam um COI). Você pode conferir a solução aqui (VS2008)
Como tal, existem algumas diferenças principais:
Cada um deles tem outros recursos também (alguns têm AOP e melhores aparelhos, mas geralmente tudo que eu quero que um COI faça é criar e recuperar objetos para mim)
Nota: as diferenças entre as diferentes recuperações de objetos de bibliotecas podem ser negadas usando o CommonServiceLocator: http://www.codeplex.com/CommonServiceLocator
Isso nos deixa com a inicialização, que é feita de duas maneiras: via código ou via configuração XML (app.config / web.config / custom.config). Alguns suportam ambos, outros suportam apenas um. Devo observar: alguns usam atributos para ajudar a IoC.
Então, aqui está minha avaliação das diferenças:
Somente inicialização de código (com atributos). Espero que você goste de lambdas. O código de inicialização fica assim:
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 inicialização ou XML ou Atributos. v2.5 também é muito lambda'y. Em suma, este é um dos meus favoritos. Algumas idéias muito interessantes sobre como o StructureMap usa os 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 inicialização e XML. Boa biblioteca, mas a configuração XML é um problema. Ótima biblioteca para a Microsoft ou as lojas da rodovia. A inicialização do código é fácil:
container.RegisterType<ICustomerRepository, CustomerRepository>()
.RegisterType<ICustomerService, CustomerService>();
XML apenas o mais próximo possível. Mas, para a funcionalidade, o Spring.Net faz tudo sob o sol que uma IoC pode fazer. Mas como a única maneira de unificar é através do XML, isso geralmente é evitado pelas lojas .net. Embora muitas lojas .net / Java usem o Spring.Net devido à semelhança entre a versão .net do Spring.Net e o projeto Java Spring.
Nota : A configuração no código agora é possível com a introdução do Spring.NET CodeConfig .
XML e código. Como o Spring.Net, o Windsor fará o que você desejar. Windsor é provavelmente um dos contêineres IoC mais populares do mercado.
IWindsorContainer container = new WindsorContainer();
container.AddComponentWithLifestyle<ICustomerRepository, CustomerRepository>("CustomerRepository", LifestyleType.Singleton);
container.AddComponentWithLifestyle<ICustomerService, CustomerService>("CustomerService",LifestyleType.Singleton);
container.AddComponent<Form1>("Form1");
Pode misturar XML e código (com v1.2). Biblioteca simples e agradável de IoC. Parece fazer o básico sem muito barulho. Oferece suporte a contêineres aninhados com escopo local de componentes e um gerenciamento de tempo de vida bem definido.
Aqui está como você inicializa:
var builder = new ContainerBuilder();
builder.Register<CustomerRepository>()
.As<ICustomerRepository>()
.ContainerScoped();
builder.Register<CustomerService>()
.As<ICustomerService>()
.ContainerScoped();
builder.Register<Form1>();
Se eu tivesse que escolher hoje: provavelmente iria com o StructureMap. Possui o melhor suporte para os recursos da linguagem C # 3.0 e a maior flexibilidade na inicialização.
Nota : Chris Brandsma transformou sua resposta original em uma postagem no blog .
Até onde eu vi, eles são praticamente os mesmos, exceto por alguns detalhes de implementação aqui e ali. A maior vantagem que o Unity tem sobre a concorrência é que ela é fornecida pela Microsoft; existem muitas empresas por aí que têm medo do OSS.
Uma desvantagem é que ela é bastante nova e pode ter bugs que os jogadores mais velhos já resolveram.
Dito isto, você pode querer verificar isso .
Tópico antigo, mas como essa é a primeira coisa que o Google me mostrou quando eu digitei unity vs spring.net ...
O Spring faz o CodeConfig agora, se você não gosta da configuração XML
http://www.springframework.net/codeconfig/doc-latest/reference/html/
Além disso, o Spring é muito mais do que apenas um contêiner DI, se você olhar para a seção 'Módulos' nos documentos, o contêiner DI é a base da enorme pilha de coisas que faz.
Corrija-me se eu estiver enganado, mas acho que o Autofac oferece suporte à Configuração XML, conforme listado neste link: Configuração do Autofac XML
O Spring possui um recurso que pode injetar parâmetros no construtor ou na propriedade com base no nome ou na posição do parâmetro. Isso é muito útil se o parâmetro ou propriedade for um tipo simples (por exemplo, um número inteiro, um booleano). Veja o exemplo aqui . Eu não acho que isso realmente compensa a incapacidade do Spring de fazer a configuração no código.
O Windsor também pode fazer isso, e pode fazê-lo no código não config. (corrija-me se estiver errado, estou apenas passando pelo que ouvi aqui).
Eu gostaria de saber se o Unity pode fazer isso.
Uma coisa a observar: Ninject é o único contêiner de IoC que suporta injeções de dependência contextual (conforme o site). No entanto, como não tenho experiência com outros contêineres IoC, não sei dizer se isso é válido.
Apenas para adicionar meus 2 centavos, tentei o StructureMap e o Unity. Achei o StructureMap mal documentado / mal orientado, uma dor no bumbum para configurar e desajeitado para usar. Da mesma forma, ele não parece suportar cenários como substituições de argumentos do construtor no momento da resolução, que foi um ponto de uso importante para mim. Então larguei e fui com o Unity, e fiz o que eu queria em cerca de 20 minutos.
Eu pessoalmente uso o Unity, mas apenas porque é da Microsoft. Lamento a decisão por uma razão: a maior coisa que ela tem contra ela tem um grande "bug" que faz com que ela sempre lance exceções. Você pode ignorar as exceções durante a depuração. No entanto, o aplicativo fica extremamente lento se você o encontrar, pois lançar uma exceção é uma operação cara. Por exemplo, atualmente estou "corrigindo" essa exceção em um ponto do meu código em que as exceções do Unity adicionam mais 4 segundos ao tempo de renderização da página. Para mais detalhes e uma solução alternativa, consulte:
O Unity pode ser feito para não lançar SynchronizationLockException o tempo todo?