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.