Alkampfer's Place

Il blog di Gian Maria Ricci
posts - 659, comments - 871, trackbacks - 80

My Links

News

Gian Maria Ricci Mvp Logo CCSVI in Multiple Sclerosis

English Blog

Tag Cloud

Article Categories

Archives

Post Categories

Image Galleries

I miei siti

Siti utili

Castle Vs Spring Override delle properties

Una delle funzionalità di Castle.Windsor che non ho trovato su spring, e si fa anche un po fatica a simularla, è la possibilità di fare un override delle proprietà di un oggetto. Mi spiego meglio. Se io ho un oggetto configurato in Windsor in questo modo

public class AlertManager {

private IMessageSender mSender;

public AlertManager(IMessageSender sender) {
mSender = sender;
}

public ILogger Logger {
get { return mLogger; }
set { mLogger = value; }
}
private ILogger mLogger = DevNullLogger.Instance;

public void Alert(String message) {
mSender.Send(
"Alert received", message);
if (mLogger.IsDebugEnabled)
mLogger.LogDebug(
String.Format("Alert send {0} message", message));
}
}

<component
id="AlertManager"
service="IoC.AlertManager, IoC"
type="IoC.AlertManager, IoC"
lifestyle="Transient"
inspectionBehavior="all">
<parameters>
<sender>${MailSender}</sender>
<Logger>${Log4NetLogger}</Logger>
</parameters>
</component>

Ho dichiarato che il componente AlertManager ha due dipendenze, una chiamata sender che si riferisce al componente SenderList, l'altra chiamata logger che si riferisce ad un Log4NetLogger. Se utilizzo il metodo Resolve() del container ottengo l'oggetto completamente configurato, ma supponiamo che abbia bisogno in qualche particolare situazione di configurare diversamente l'oggetto, ad esempio in un test. Una possibile soluzione è creare nel file di configurazione un'altra entry per AlertManager con un differente id e poi utilizzare la Resolve(String), ma anche questa soluzione è incompleta, perché spesso ho bisogno di passare una specifica istanza di oggetto, ad esempio un mock object. Questa esigenza è pienamente supportata da Windsor che fornisce il metodo Resolve(IDictionary), il quale accetta coppie "String", object che permettono di fare un override del valore di alcune proprietà. Personalmente nella mia classe Wrapper IoC dichiaro inoltre sempre questo metodo

public static T Resolve<T>(params object[] values) {
System.Collections.
Hashtable arguments = new System.Collections.Hashtable();
for (Int32 I = 0; I < values.Length; I += 2) {
arguments.Add(values[I], values[I + 1]);
}
return ActualContainer.Resolve<T>(arguments);
}

Perché trovo che la lista variabile di parametri sia in qualche modo più utilizzabile. Ora posso ad esempio fare

MailSender ms = new MailSender("a@a.it");
AlertManager alm = IoC.Resolve<AlertManager>("sender", ms);

In questo modo sto chiedendo a Windsor di creare un AlkertManager ma di assegnare il mio MailSender ad ogni proprietà di nome sender. Windsor inoltre ha un forte autowiring per cui è possibile ottenere lo stesso risultato in questo modo

AlertManager alm = IoC.Resolve<AlertManager>("mailAddress", "a@a.it");

In questo caso ho cambiato una dipendenza non dell'oggetto AlertManager, ma della proprietà mailAddress dell'oggetto MailSender. Personalmente trovo questa possibilità veramente fantastica.

Alk.

Print | posted on Friday, August 3, 2007 8:12 AM | Filed Under [ Castle ]

Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET