Enterprise Library Unity vs altri contenitori IoC [chiuso]


135

Quali sono i pro e i contro dell'utilizzo di Enterprise Library Unity rispetto ad altri container IoC (Windsor, Spring.Net, Autofac ..)?


9
Questi tipi di domande sono sempre chiusi. Le opinioni sono importanti. C'è un posto dove posizionarli?
Jeson Martajaya,

1
@JesonMartajaya, volevo elogiare esattamente lo stesso commento, è fastidioso che le domande vengano chiuse, ma nessuna risposta per un'alternativa.
Mohammed Noureldin,

Risposte:


234

Sto preparando una presentazione per un gruppo di utenti. Come tale, ne ho appena esaminati un mucchio. Vale a dire: AutoFac, MEF, Ninject, Spring.Net, StructureMap, Unity e Windsor.

Volevo mostrare il caso del 90% (iniezione del costruttore, che è principalmente ciò per cui le persone usano un CIO). Puoi consultare la soluzione qui (VS2008)

Come tale, ci sono alcune differenze chiave:

  • Inizializzazione
  • Recupero dell'oggetto

Ognuno di loro ha anche altre funzionalità (alcuni hanno AOP e aggeggi migliori, ma generalmente tutto ciò che voglio fare un CIO è creare e recuperare oggetti per me)

Nota: le differenze tra le diverse librerie di recupero degli oggetti possono essere annullate utilizzando CommonServiceLocator: http://www.codeplex.com/CommonServiceLocator

Questo ci lascia con l'inizializzazione, che viene eseguita in due modi: tramite codice o tramite configurazione XML (app.config / web.config / custom.config). Alcuni supportano entrambi, altri ne supportano solo uno. Dovrei notare: alcuni usano attributi per aiutare l'IoC insieme.

Quindi, ecco la mia valutazione delle differenze:

Ninject

Solo inizializzazione del codice (con attributi). Spero ti piacciano le lambdas. Il codice di inizializzazione è simile al seguente:

 IKernel kernel = new StandardKernel(
                new InlineModule(
                    x => x.Bind<ICustomerRepository>().To<CustomerRepository>(),
                    x => x.Bind<ICustomerService>().To<CustomerService>(),
                    x => x.Bind<Form1>().ToSelf()
                    ));

StructureMap

Codice di inizializzazione o XML o attributi. v2.5 è anche molto lambda. Tutto sommato, questo è uno dei miei preferiti. Alcune idee molto interessanti su come StructureMap utilizza gli attributi.

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

Unità

Codice di inizializzazione e XML. Bella libreria, ma la configurazione XML è una seccatura. Grande biblioteca per Microsoft o i negozi dell'autostrada. L'inizializzazione del codice è semplice:

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

Spring.NET

XML solo il più vicino possibile. Ma per funzionalità Spring.Net fa tutto sotto il sole che un IoC può fare. Ma poiché l'unico modo per unità è attraverso XML è generalmente evitato dai negozi .net. Tuttavia, molti negozi .net / Java utilizzano Spring.Net a causa della somiglianza tra la versione .net di Spring.Net e il progetto Java Spring.

Nota : la configurazione nel codice è ora possibile con l'introduzione di CodeConfig Spring.NET .

Windsor

XML e codice. Come Spring.Net, Windsor farà qualsiasi cosa tu possa desiderare. Windsor è probabilmente uno dei container IoC più popolari in circolazione.

IWindsorContainer container = new WindsorContainer();
container.AddComponentWithLifestyle<ICustomerRepository, CustomerRepository>("CustomerRepository", LifestyleType.Singleton);
container.AddComponentWithLifestyle<ICustomerService, CustomerService>("CustomerService",LifestyleType.Singleton);
container.AddComponent<Form1>("Form1");

autofac

Può mescolare sia XML che codice (con v1.2). Bella libreria IoC semplice. Sembra fare le basi senza troppa confusione. Supporta contenitori nidificati con ambito locale dei componenti e una gestione della vita definita.

Ecco come inizializzarlo:

var builder = new ContainerBuilder();
builder.Register<CustomerRepository>()
        .As<ICustomerRepository>()
        .ContainerScoped();
builder.Register<CustomerService>()
        .As<ICustomerService>()
        .ContainerScoped();
builder.Register<Form1>();

Se dovessi scegliere oggi: probabilmente andrei con StructureMap. Offre il miglior supporto per le funzionalità del linguaggio C # 3.0 e la massima flessibilità nell'inizializzazione.

Nota : Chris Brandsma ha trasformato la sua risposta originale in un post sul blog .


1
Solo configurazione XML, che rende molto più difficile la configurazione. Fondamentalmente, le uniche persone che vedo che vogliono usare Spring.Net sono ex sviluppatori Java.
Chris Brandsma,

Chris, per quanto riguarda le tue conclusioni: puoi per favore fornire qualche dettaglio in più su a) a quali caratteristiche di C # 3 ti riferisci eb) a quali tipi di inizializzazione sono importanti per te? Grazie!
Nicholas Blumhardt,

2
Ciao Nicholas: per quanto riguarda il supporto per C # 3, tutto ciò che Autofac fa già. :) Per l'inizializzazione, desidero un supporto semplice per singleton / non singletons e inizializzazione per sessione. Infine, voglio modi semplici per fare riferimento per nome personalizzato. (qualcosa che è una PITA in StructureMap). L'ultima caratteristica che mi piace di più ora rispetto a quando ho scritto questo in origine: AutoMocking. Non lo uso sempre, ma è bello avere aunt.
Chris Brandsma,

Hai menzionato anche MEF, io uso MEF per fornire i miei oggetti di implementazione IRepository e trovo che funzioni bene. Cosa ne pensi di MEF?
terjetyl,

Ecco un bel screencast di 20 minuti che mostra la maggior parte di Unity: pnpguidance.net/Screencast/…
Pat

7

Per quanto ho visto, sono praticamente uguali, ad eccezione di alcuni dettagli di implementazione qua e là. Il più grande vantaggio di Unity rispetto alla concorrenza è che è fornito da Microsoft, ci sono molte aziende là fuori che hanno paura dell'OSS.

Uno svantaggio è che è piuttosto nuovo, quindi potrebbe avere dei bug che i giocatori più anziani hanno già risolto.

Detto questo, potresti voler dare un'occhiata .


4

Vecchio thread, ma poiché questa è la prima cosa che Google mi ha mostrato quando ho digitato unità vs spring.net ...

Spring fa CodeConfig ora se non ti piace la configurazione XML

http://www.springframework.net/codeconfig/doc-latest/reference/html/

Inoltre, Spring è molto più di un semplice contenitore DI, se dai un'occhiata alla sezione "Moduli" nei documenti, il contenitore DI è il fondamento dell'enorme pila di cose che fa.


3

Correggimi se sbaglio, ma penso che Autofac stesso supporti la configurazione XML come elencato in questo link: Configurazione XML Autofac


2

Spring ha una caratteristica che può iniettare parametri nel costruttore o nella proprietà in base al nome o alla posizione del parametro. Ciò è molto utile se il parametro o la proprietà è un tipo semplice (ad esempio un numero intero, un valore booleano). Vedi l'esempio qui . Non penso che ciò compensi davvero l'incapacità di Spring di configurare il codice.

Windsor può anche fare questo, e può farlo in codice non configurato. (correggimi se sbaglio, sto solo passando quello che ho sentito qui).

Vorrei sapere se Unity può farlo.



1

Solo per aggiungere i miei 2 centesimi, ho provato sia StructureMap che Unity. Ho trovato StructureMap per essere scarsamente / mal documentato, un dolore nel calcio da configurare e ingombrante da usare. Allo stesso modo, non sembra supportare scenari come l'argomento del costruttore ha la precedenza al momento della risoluzione, che è stato un punto di utilizzo chiave per me. Così l'ho lasciato cadere, sono andato con Unity e l'ho fatto fare quello che volevo in circa 20 minuti.


1

Personalmente uso Unity, ma solo perché proviene da Microsoft. Mi rammarico della decisione per un motivo: la cosa più grande che ha contro di essa ha un grosso "bug" che gli fa costantemente generare eccezioni. È possibile ignorare le eccezioni durante il debug. Tuttavia, se ci si imbatte in essa rallenta enormemente l' applicazione , poiché generare un'eccezione è un'operazione costosa. Ad esempio, attualmente sto "sistemando" questa eccezione in un punto del mio codice in cui le eccezioni di Unity aggiungono altri 4 secondi al tempo di rendering di una pagina. Per ulteriori dettagli e una soluzione alternativa, vedere:

Si può fare Unity per non lanciare SynchronizationLockException tutto il tempo?


Grazie per l'avviso! In base a questa risposta dalla domanda a cui hai fatto riferimento , il bug è ora risolto.
Sam

Perché Unity lancia un'eccezione? Di solito un'eccezione è un "errore critico" (come una dipendenza irrisolvibile) e non qualcosa da eliminare.
user2864740

Mi scusi, questo "bug" è stato risolto o hai trovato il modo di evitarlo? sto scegliendo framework in c # .net ora e desideroso di sapere se l'unità costa ancora tempo ...
Jog Dan
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.