119

Ho letto gli articoli su MSDN su Unity (Dependency Injection, Inversion of Control), ma penso di averne bisogno spiegato in termini semplici (o semplici esempi). Ho familiarità con il pattern MVPC (lo usiamo qui), ma non riesco ancora a cogliere questa cosa Unity, e penso che sia il prossimo passo nel design delle nostre applicazioni.Qualcuno può spiegare Microsoft Unity?

+4

Mi piace come questo abbia lo stesso nome di "Unity", quindi quando cerco oggetti di Unity Game Engine vedo questa vecchia tecnologia, sospiro. Tutti i nomi delle buone band sono presi, suppongo. –

risposta

139

Unity è solo un "contenitore" IoC. Google StructureMap e provalo invece. Un po 'più facile da battere, penso, quando le cose di IoC sono nuove per te.

Fondamentalmente, se capisci IoC capisci che quello che stai facendo è invertire il controllo per quando un oggetto viene creato.

Senza Cio:

public class MyClass 
{ 
    IMyService _myService; 

    public MyClass() 
    { 
     _myService = new SomeConcreteService();  
    } 
} 

Con contenitore CIO:

public class MyClass 
{ 
    IMyService _myService; 

    public MyClass(IMyService myService) 
    { 
     _myService = myService;  
    } 
} 

Senza CIO, la classe che si basa sulla IMyService deve nuova-up di una versione concreta del servizio da utilizzare. E ciò non va bene per una serie di motivi (hai abbinato la tua classe a una specifica versione concreta di IMyService, non puoi testarlo facilmente, non puoi cambiarlo facilmente, ecc.)

Con un container IoC "configura" il contenitore per risolvere tali dipendenze per te. Quindi con uno schema di iniezione basato sul costruttore, si passa semplicemente l'interfaccia alla dipendenza IMyService nel costruttore. Quando crei MyClass con il tuo contenitore, il tuo contenitore risolverà la dipendenza IMyService per te.

Utilizzando StructureMap, configurando il contenitore si presenta così: "Quando qualcuno richiede l'IMyService, dare loro una copia del SomeConcreteService"

StructureMapConfiguration.ForRequestedType<MyClass>().TheDefaultIsConcreteType<MyClass>(); 
StructureMapConfiguration.ForRequestedType<IMyService>().TheDefaultIsConcreteType<SomeConcreteService>(); 

Quindi, quello che hai fatto è raccontato il contenitore, E hai anche specificato che quando qualcuno chiede una MyClass, ottiene una MyClass concreta.

Questo è tutto ciò che fa realmente un contenitore IoC. Possono fare di più, ma questo è il loro scopo: risolvono le dipendenze per te, quindi non devi (e non devi usare la "nuova" parola chiave nel tuo codice).

passo finale: quando si crea il MyClass, si dovrebbe fare questo:

var myClass = ObjectFactory.GetInstance<MyClass>(); 

Speranza che aiuta. Sentiti libero di inviarmi un'e-mail.

+2

Quindi è come una fabbrica, suppongo?Se sto seguendo questo correttamente, non useresti invece di nell'esempio finale? quindi var myClass = ObjectFactory.GetInstance ()? Grazie per il tuo aiuto, questo è un buon inizio per me! –

+3

In un certo senso, è come una fabbrica, sì. Una fabbrica principale per la tua applicazione. Ma può essere configurato per restituire molti tipi diversi, inclusi i singleton. Per quanto riguarda l'interfaccia con MyClass, se si tratta di un oggetto business, non estrarre un'interfaccia. Per tutto il resto, lo farei generalmente. –

+0

cosa succede se si chiama ObjectFactory.GetInstance solo (); e non hai configurato il SomeConcreteClass? Vuoi ottenere e l'errore in tal caso? – RayLoveless

27

Unity è una libreria come molte altre che consente di ottenere un'istanza di un tipo richiesto senza doverla creare personalmente. Così dato.

public interface ICalculator 
{ 
    void Add(int a, int b); 
} 

public class Calculator : ICalculator 
{ 
    public void Add(int a, int b) 
    { 
     return a + b; 
    } 
} 

Si potrebbe utilizzare una libreria come unità per registrare Calcolatrice da restituire quando viene richiesto il tipo di ICalculator alias IOC (Inversion of Control) (questo esempio è teorico, non è tecnicamente corretto).

IoCLlibrary.Register<ICalculator>.Return<Calculator>(); 

Così ora quando si desidera un'istanza di un ICalculator basta ...

Calculator calc = IoCLibrary.Resolve<ICalculator>(); 

librerie IoC di solito può essere configurato per tenere un singolo o creare una nuova istanza ogni volta a risolvere un genere.

Ora diciamo che si dispone di una classe che si basa su un ICalculator di essere presente si potrebbe avere ..

public class BankingSystem 
{ 
    public BankingSystem(ICalculator calc) 
    { 
     _calc = calc; 
    } 

    private ICalculator _calc; 
} 

E si può impostare la libreria di iniettare un oggetto nel costruttore quando viene creato.

Quindi DI o Dipendenza Iniezione significa iniettare qualsiasi oggetto che possa essere richiesto da un altro.

8

Unity è un IoC. Il punto di IoC è di astrarre il cablaggio delle dipendenze tra tipi al di fuori dei tipi stessi. Questo ha un paio di vantaggi. Prima di tutto, è fatto centralmente, il che significa che non è necessario cambiare molto codice quando cambiano le dipendenze (che potrebbe essere il caso dei test unitari).

Inoltre, se il cablaggio viene eseguito utilizzando i dati di configurazione anziché il codice, è possibile ricablare le dipendenze dopo la distribuzione e quindi modificare il comportamento dell'applicazione senza modificare il codice.

35

Ho appena visto i 30 minuti di Unity Dependency Injection IoC Screencast di David Hayden e ho ritenuto che fosse una buona spiegazione con esempi. Ecco un frammento dalle note spettacolo:

La screencast mostra diversi usi comuni dell'Unità CIO, come ad esempio:

  • Creazione di tipi di Not In Contenitore
  • Registrazione e TypeMappings Risoluzione
  • Registrazione e Risolvi TypeMappings con nome
  • Singletons, LifetimeManagers e ContainerControlledLifetimeManager
  • Registrazione di istanze esistenti
  • Iniettare dipendenze in istanze esistenti
  • popolamento l'UnityContainer tramite app.config/web.config
  • Specifica dipendenze tramite API iniezione anziché Dipendenza attributi
  • Uso nidificati (padre-figlio) Container
4

MSDN ha un Developer's Guide to Dependency Injection Using Unity che potrebbe essere utile.

La Guida per lo sviluppatore inizia con le basi di ciò che è l'iniezione di dipendenza e continua con esempi su come utilizzare Unity per l'iniezione delle dipendenze. A partire da febbraio 2014, la Guida dello sviluppatore copre Unity 3.0, che è stata rilasciata nell'aprile 2013.