12

potrebbe sembrare una domanda stupida, perché nel mio codice che tutto funzioni, ma ho registrato un singleton in questo modo con il mio contenitore Unità _ambientContainer:UnityContainer.Resolve o ServiceLocator.GetInstance?

_ambientContainer.RegisterType<Application.StateContext>(new ContainerControlledLifetimeManager()); 

Al fine di evitare di usare il mio campo locale, io uso :

get { 
    return ServiceLocator.Current.GetInstance<Application.StateContext>(); 
} 

all'interno della proprietà get per ottenere un'istanza del mio oggetto. In questo modo ottengo sempre la stessa istanza (Application.StateContext è ancora un singleton) oppure lo GetInstance ne crea uno nuovo?

È preferibile utilizzare il campo locale _ambientContainer?

get { 
    return _ambientContainer.Resolve<Application.StateContext>(); 
} 

Grazie.

risposta

7

Preferibilmente si dovrebbe evitare di entrambi i modi di (ab) utilizzando il contenitore.

Il ServiceLocator is considered an anti-pattern nella moderna architettura dell'applicazione.

+1

Avete un suggerimento di un'alternativa? (specifico per il codice di esempio nella domanda?) – Adam

+0

@Adam Un'alternativa a quale codice? Il getter? O la registrazione di 'Application.StateContext'? L'autore non ha detto che tipo di applicazione utilizza (asp.net/mcv, winforms, wpf, console, wcf ...), quindi non posso dire che dovresti inserire il codice di registrazione. Ogni tipo di app ha una diversa [radice di composizione] (http://blog.ploeh.dk/2011/07/28/CompositionRoot.aspx). Per quanto riguarda la chiamata al localizzatore di servizi: rendere 'StateContext' un parametro ctor di quelle classi che ne hanno bisogno. Ciò rende la dipendenza esplicita e intercambiabile (ad esempio per i test). –

+1

Qualsiasi modello è un pattern anti se lo si utilizza nel modo sbagliato. TUTTE le librerie DI utilizzano la posizione del servizio sotto le copertine, altrimenti non funzionano. Non credere a tutto ciò che leggi su internet! – JBeckton

15

passando intorno istanze del contenitore per le classi di consumo non è generalmente una buona idea, dal momento che non si è più garantito per avere un unico luogonell'applicazione in cui sono stati registrati componenti e servizi (noto come il Composition Root) .

Classi di indicare loro dipendenze nel loro API pubblica, idealmente specifying them as constructor arguments, quale il contenitore fornirà automaticamente un'istanza per ogni volta che è stato chiesto di risolvere un tipo specifico (un processo noto come autowiring).

Dependency Injection è in genere the preferred choice ma non è sempre applicabile. In questi casi, l'utilizzo di un numero Service Locator, come nel tuo esempio, è il successivo migliore soluzione a decouple a class from its dependencies.

In conclusione, se l'opzione Dipendenza iniezione non è un'opzione, eviterei di fare in modo che le mie classi facciano riferimento al contenitore direttamente e invece di accedervi tramite un Localizzatore di servizi.