2012-12-26 22 views
8

Occasionalmente mi trovo in una situazione in cui devo risolvere un servizio solo se viene soddisfatta una determinata condizione. Ad esempio, un utente potrebbe scegliere di inviare un messaggio di posta elettronica o una notifica di sms. Vorrei caricare pigro il servizio email o sms a seconda di cosa l'utente sceglie in modo che non debba caricarli entrambi e sprecare risorse (e se ci fossero, per esempio, 10 opzioni per l'utente ...?).Servizio di carico lento Castle Windsor

Il problema che ho è con l'utilizzo del contenitore al di fuori del mio codice di bootstrap (non voglio che il mio codice dipenda dal contenitore). Non riesco a trovare un modo per utilizzare il contenitore per i servizi di caricamento lazy (a meno che non crei manualmente i servizi necessari e eseguo manualmente tutti i DI). È una situazione in cui le regole possono essere piegate o esiste un modo migliore per farlo?

risposta

5

Se si utilizza Castle Windsor 3.0 o successivo, è possibile utilizzare la risoluzione lenta.

Vedere What's new in Windsor 3 for more details.

Il processo di registrazione cambia leggermente (è necessario registrare un nuovo caricatore di componenti).

Dopodiché, si stanno solo registrando i componenti come sempre, ma si risolvono le dipendenze come Lazy<T> anziché T. Finché non avrai accesso alla proprietà .Value del tuo Lazy<T>, la dipendenza non verrà risolta, quindi puoi passare alcuni oggetti ponderati e accedere solo a quello che ti servirà e quando necessario.

Se si dispone di più opzioni per l'utente, forse si dovrebbe prendere in considerazione la creazione di una sorta di interfaccia di fabbrica astratta. Dovresti quindi registrare e risolvere solo questa fabbrica e la fabbrica stessa creerebbe un servizio appropriato per l'invio di notifiche (sia esso una mail o un sms o qualsiasi altra opzione). L'implementazione della fabbrica può essere codificata a mano o Castle Windsor può farlo (penso dalla versione 3.0).

Spesso quando utilizzo tale factory, lo implemento manualmente e il contenitore passa in quanto è dipendente, quindi solo l'implementazione di fabbrica dipende dal mio contenitore.

1

In generale, è possibile farlo con Typed Factory Facility.

In poche parole, quando si risolve il componente che utilizza tali servizi, invece di dare un servizio di e-mail o sms, si dà un fabbrica che può creare loro (che è definito da voi, senza riferimenti al container)

La struttura si occuperà di "implementare" la tua fabbrica (dall'interfaccia che crei), quindi c'è ben poco da fare.

+0

E se ognuno dei miei servizi ha il suo insieme unico di dipendenze. Ad esempio, il servizio sms ha 3 dipendenze univoche, il servizio di posta elettronica ha 4 dipendenze univoche, ecc. Devo solo iniettare 20 (o comunque molte dipendenze) in fabbrica? Grande risposta tra – orourkedd

+0

La fabbrica è implementata dal castello. Devi semplicemente configurare i tuoi servizi come al solito. –

2

Solo un esempio per semplificare (sulla base di Marcin Deptula risposta)

// activate Lazy initialization feature for all Components 
.Register(Component.For<ILazyComponentLoader>().ImplementedBy<LazyOfTComponentLoader>())  
// register rest of component(s) 
.Register(Component.For<IIssueRepository>().ImplementedBy<IssueRepository>()) 
. .... 

determinazione pigramente (proprietà di iniezione)

public Lazy<IIssueRepository> IssueRepository { get; set; } 
IssueRepository.Value.GetLastIssue(); 

determinazione normale (proprietà di iniezione)

public IIssueRepository IssueRepository { get; set; } 
IssueRepository.GetLastIssue(); 
Problemi correlati