Quali sono i pro e i contro dell'utilizzo di Enterprise Library Unity rispetto ad altri container IoC (Windsor, Spring.Net, Autofac ..)?
Quali sono i pro e i contro dell'utilizzo di Enterprise Library Unity rispetto ad altri container IoC (Windsor, Spring.Net, Autofac ..)?
Risposte:
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:
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:
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()
));
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>();
});
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>();
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 .
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");
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 .
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 .
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.
Correggimi se sbaglio, ma penso che Autofac stesso supporti la configurazione XML come elencato in questo link: Configurazione XML Autofac
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.
Una cosa da notare: Ninject è l'unico contenitore IoC che supporta iniezioni di dipendenza contestuali (come per il loro sito Web). Tuttavia, poiché non ho esperienza con altri contenitori IoC, non so dire se ciò sia valido.
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.
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?