7

Problema:Crea istanza di una classe con dipendenze utilizzando Autofac

Assumere il classe:

public class MyAwesomeClass 
{ 
    private IDependCls _dependCls; 
    public MyAwesomeClass(IDependCls dependCls) 
    { 
     _dependCls = dependCls; 
    } 

} 

E da qualche altra parte ho bisogno di ottenere un'istanza di quella classe, in questo modo:

public class SomewhereElse 
{ 
    public void AwesomeMethod() 
    { 
     //... 
     // AwesomeStuff 
     //... 

     var GetErDone = new MyAwesomeClass(); // PROBLEM! No constructor with 0 arguements 
    } 
} 

La domanda è, faccio a

Soluzione proposta 1:

A) è necessario creare un constuttore aggiuntivo che risolva la dipendenza? Per esempio:

public MyAwesomeClass() // new constructor 
    { 
     _dependCls = DependencyResolver.Current.GetService<IDependCls>(); 
    } 


public class SomewhereElse 
{ 
    public void AwesomeMethod() 
    { 
     var GetErDone = new MyAwesomeClass(); // IT WORKS!! 
    } 
} 

Soluzione proposta 2:

B) utilizzare il risolutore all'interno AwesomeMethod destra prima var GetErDone

public class SomewhereElse 
{ 
    public void AwesomeMethod() 
    { 
     var depCls = _dependCls = DependencyResolver.Current.GetService<IDependCls>(); 
     var GetErDone = new MyAwesomeClass(depCls); // IT WORKS!! 
    } 
} 

soluzione Autofac?

C) Qualche altro modo Autofac?

cerca di migliori pratiche, così come una buona soluzione Autofac se possibile. Penso che la prima sia la peggiore in quanto le dipendenze opzionali potrebbero portare a un sacco di confusione.

Sommario:

Come faccio a ottenere un new MyAwesomeClass() quando MyAwesomeClass ha dipendenze?

+0

Intendi davvero _optional_ quando lo dici? Se è davvero opzionale, potresti voler esaminare l'iniezione di proprietà. In caso contrario, e il tuo amministratore è ingombrato a causa di troppe dipendenze, forse la tua classe sta facendo troppo (vedi anche [questa risposta] (http://stackoverflow.com/a/2420245/1282778)). –

+0

Non ho una domanda sull'ingombro del costruttore, piuttosto che creare un'istanza di una classe che necessita dell'iniezione del costruttore. –

+0

Grazie per non aver inviato la risposta alla soluzione. Non come nessun altro ha questo problema .../s –

risposta

7

Avere uno sguardo al modello Composition Root.

Hai ragione, tirando su la risoluzione delle dipendenze sposta solo il problema in un altro posto. Se continui a spostarlo verso l'alto nel tuo grafico oggetto, però, raggiungerai il punto di ingresso della tua applicazione. Lì comporrai il tuo oggetto grafico.

Confronta che al Service Locator anti-pattern (utilizzando DependencyResolver in classi client nel tuo caso) e vedrete che la composizione Root è una soluzione superiore.

+0

Grazie per la risposta. +1 perché hai davvero una comprensione del concetto e grazie per il tuo articolo. Quindi immagino che questo accadrà inevitabilmente? Ho intenzione di leggere questo approccio in più, ma penso che l'effettiva radice di composizione come la chiami dovrebbe essere la dichiarazione della rilegatura stessa. Altrimenti, infrangi la singola responsabilità e la regola della separazione delle preoccupazioni. –

+0

Sì, la Composizione radice è definita in modo astratto come una "posizione", è possibile suddividerla in più classi, ma è importante che siano contenute nello stesso assieme. Mark Seemann, l'autore degli articoli, ha scritto [un grande libro] (http://www.amazon.com/Dependency-Injection-NET-Mark-Seemann/dp/1935182501) su DI btw. –

+1

@Mihalis - Hai mai ottenuto una soluzione soddisfacente utilizzando il pattern di Composizione o altro.Il codice di esempio è facile da seguire e mi piacerebbe vedere il codice per la terza soluzione - thans –

0

Se si desidera risolvere automaticamente via Autofac esempio, è possibile scegliere solo da questo

  • Iniettare nella costruzione della classe di
  • Inject in proprietà, utilizzando

    var builder = new ContainerBuilder();

    builder.RegisterType<Foo>().PropertiesAutowired();

  • Usa accesso globale da DependencyResolver.Current.GetService<IFoo>();

+0

Sto usando l'iniezione del costruttore ma sto chiedendo il processo effettivo di creazione di un'istanza di quella classe. –

+0

Cosa intendi con processo di creazione di un'istanza di quella classe? Che classe vuoi istanziare? E cosa vuoi esattamente fare? Più informazioni –

+0

Si prega di vedere il secondo blocco grigio. Se uso il codice così com'è, ottengo un problema (ovviamente). Poi, propongo 2 soluzioni che non mi piacciono, e chiedo un terzo - o una conferma che una delle 2 che propongo è una pratica standard. Aggiornerò la risposta per includere effettivamente le mie soluzioni per farvi vedere –

0

Nella classe contenente MyAwesomeMethod prendere MyAwesomeClass come una dipendenza costruttore. Autofac si prenderà cura dell'istanziazione.

+0

sì ma questo sposta semplicemente il problema di una classe più in alto, questo è il punto in cui sono effettivamente. Cosa succede se voglio creare un'istanza della classe che contiene 'MyAwesomeMethod'? –

0

Prima di tutto oltre all'iniezione del costruttore è possibile utilizzare anche property injection e method injection. Tuttavia, l'iniezione del costruttore è più comune e il metodo più veloce, quindi suggerisco di attenervisi.

La seconda cosa che devi fare è registrare il tuo MyAwesomeClass nel contenitore Autofac insieme con la sua dipendenza, hanno qualche bello examples proprio nella loro home page.

E l'ultima cosa: non è necessario creare istanze di MyAwesomeClass direttamente, utilizzare invece Autofac. Ecco un esempio aggiornato:

public void AwesomeMethod() 
{ 
    //... 
    // AwesomeStuff 
    //... 

    var GetErDone = DependencyResolver.Current.GetService<MyAwesomeClass>(); 
} 
+0

creerà una nuova istanza o un servizio già registrato? – theusguy

Problemi correlati