Unidade da biblioteca corporativa versus outros contêineres IoC [fechado]

135

Quais são os prós e os contras do uso do Enterprise Library Unity versus outros contêineres IoC (Windsor, Spring.Net, Autofac ..)?

Yoann. B
fonte
9
Esses tipos de perguntas estão sempre fechados. As opiniões são importantes. Existe um lugar onde colocá-los?
Jeson Martajaya
1
@JesonMartajaya, eu queria elogiar exatamente o mesmo comentário, é irritante que as perguntas estejam fechando, mas não há resposta para uma alternativa.
Mohammed Noureldin 19/10/19

Respostas:

234

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:

  • Inicialização
  • Recuperação de objeto

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:

Ninject

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

StructureMap

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

Unidade

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

Spring.NET

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 .

Windsor

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

Autofac

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 .

Chris Brandsma
fonte
1
Somente configuração XML, dificultando muito a configuração. Basicamente, as únicas pessoas que vejo que desejam usar o Spring.Net são ex-desenvolvedores de Java.
23420 Chris Brandsma
Chris, em relação às suas conclusões: você pode fornecer mais detalhes sobre a) quais recursos do C # 3 você está se referindo eb) que tipos de inicialização são importantes para você? Obrigado!
Nicholas Blumhardt
2
Olá Nicholas: quanto ao suporte ao C # 3, tudo o que o Autofac já faz. :) Para inicialização, desejo suporte fácil para singletons / não singletons e inicialização por sessão. Finalmente, quero maneiras fáceis de fazer referência por nome personalizado. (algo que é uma PITA no StructureMap). O recurso final que eu mais gosto agora do que quando escrevi isso originalmente: AutoMocking. Eu não uso o tempo todo, mas é muito bom ter uma conta.
22620 Chris Brandsma
Você mencionou o MEF também, eu uso o MEF para entregar meus objetos de implementação do IRepository e acho que funciona bem. O que você acha do MEF?
Terjetyl 27/11/2009
Aqui está um bom, 20 minutos screencast apresentando mais de Unidade: pnpguidance.net/Screencast/...
Pat
7

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 .

rodbv
fonte
4

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.

Richard
fonte
3

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


fonte
2

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.

Anthony
fonte
2

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.

ehsanullahjan
fonte
Se tudo isso "injeção de dependência contextual" estiver no Ninject, então ... uhh, nada de especial. Suportado (por vários meios) no Unity, AutoFac, Windsor pelo menos.
user2864740
1

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.

Jacobs Data Solutions
fonte
1

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?

Josh Mouch
fonte
Obrigado pelo aviso! De acordo com esta resposta da pergunta a que você se referiu , o bug está resolvido.
25413 Sam
Por que o Unity está lançando uma exceção? Normalmente, uma exceção é um 'erro crítico' (como a dependência unreolveable) e não algo a ser suprimida ..
user2864740
Com licença, esse "bug" foi resolvido ou você encontrou uma maneira de evitá-lo? i estou escolhendo quadro no c # .net agora e ansioso para saber se a unidade é tempo-custo ainda ...
Jog Dan