2011-08-25 22 views
13

Uso Autofac per gestire l'integrazione delle dipendenze nella mia applicazione. Tuttavia, ho un componente che fa un po 'di magia di riflessione in fase di esecuzione e non so a tempo di compilazione quali dipendenze di cui avrà bisogno.Utilizzo di Autofac come localizzatore di servizio

Ordinariamente, vorrei che questo componente faccia riferimento direttamente al Container e risolva quello che vuole. Tuttavia, la classe che crea un'istanza di questa classe non ha alcun riferimento al contenitore.

In effetti, il mio componente ha una dipendenza da Autofac. Preferirei l'accoppiamento più sciolto, ma qui non sembra un'opzione. C'è un modo per chiedere (negli argomenti del costruttore, o usando l'iniezione di proprietà, o qualsiasi altra cosa!) Autofac per darmi un riferimento al contenitore nel mio costruttore? Oppure, c'è un modo più pulito per fare in modo che Autofac mi fornisca un oggetto magico di localizzazione dei servizi che possa risolvere qualsiasi cosa?

+2

Sarebbe interessante per vedere cosa "magia" sta facendo il componente. Forse ci sono altri modi oltre al modello del localizzatore di servizi. Potresti aggiornare con un po 'di codice? –

+0

Posso descriverlo abbastanza bene. Quando i messaggi arrivano su un bus, il codice determina quale tipo il messaggio utilizza alcuni metadati e quindi costruisce detto tipo. Quindi ha bisogno di trovare tutti gli implementatori di IConsume '(dove' type' è il tipo dai metadati) usando Autofac e quindi chiama il metodo Consume su di esso. –

+0

Intendi: http://kozmic.pl/2010/03/11/advanced-castle-windsor-ndash-generic-typed-factories-auto-release-and-more/ –

risposta

12

Sì, è possibile. Basta prendere una dipendenza dal IComponentContext:

public class MyComponent 
{ 
    IComponentContext _context; 
    public MyComponent(IComponentContext context) 
    { 
     _context = context; 
    } 

    public void DoStuff() 
    { 
     var service = _context.Resolve(...); 
    } 
} 

Aggiornamento dai commenti: il IComponentContext iniettati MyComponent dipende dalla portata da cui MyComponent è stato risolto. È quindi importante considerare con quale ambito di vita è registrato MyComponent. Per esempio. utilizzando InstancePerLifetimeScope, il contesto verrà sempre risolto nello stesso ambito in cui il servizio dipende da MyComponent.

+0

Funzionerà con più ambiti di validità? cioè IComponentContext sarà il contenitore di base o l'ambito? –

+3

Risolverà 'IComponentContext' dall'ambito in cui' MyComponent' è stato risolto. Quindi, se 'MyComponent' è registrato come' InstancePerLifetimeScope', 'context' verrà sempre risolto dall'ambito previsto. –

+0

Perfetto, proprio quello di cui avevo bisogno. –

1

si Supponendo che hanno due componenti, A e B.

Se A ha bisogno di sapere su X B prima di utilizzarlo, questo è Metadata interrogatori ed è descritto in questo excellent posta.

Inoltre, anche se non è possibile adattare il progetto a quel post, è necessario provare nuovamente a utilizzare realmente il contenitore DI come Localizzatore di servizi.

Al momento della stesura, il miglior post di blog che ho trovato è stato descritto come this.

+0

Non sono sicuro del motivo per cui risponderesti a una domanda già ben fatta con cose che non sono correlate alla mia domanda ... come ho detto, il mio problema non è sapere quale "B" avrò bisogno di risolvere fino al runtime. –

+1

@NikosBaxevanis +1, anche se l'OP non sembra averlo capito. Entrambi i post sono eccellenti.Questa singola frase di Nicholas post riassume tutto: "Allo stesso tempo, non ci sono praticamente scuse per usare IContainer o IComponentContext nei tuoi componenti". – rsenna

0

In altri casi, quando il componente non viene creato utilizzando DI, è comunque possibile utilizzare il modello di localizzazione del servizio. La libreria Common Service Locator su CodePlex è perfetta per lo scopo.

Problemi correlati