Sei sulla pagina 1di 68

online.infomedia.

it
n. 66 - novembre/dicembre 2005
bimestrale - anno undicesimo

Direttore Responsabile
Marialetizia Mari (mmari@infomedia.it)
Direttore Esecutivo
EDITORIALE
Francesco Balena (fbalena@infomedia.it)
Managing Editor Il valore
della conoscenza
Renzo Boni (rboni@infomedia.it)
Collaboratori
Filippo Bonanni
Stefano Corti
Raffaele Di Natale

I
Maurizio Mammuccini
Carlo Pagliei n tanti articoli su questo giornale abbiamo parlato delle tante
Fabio Perrone bellissime novità di Visual Studio, di .NET Framework 2.0 e del-
Alberto Rosotti le nuove versioni di VB e C. In questo editoriale proverò invece
Lorenzo Vandoni
a fare qualche riflessione più “metodologica” che “tecnologica”.

Partiamo con i linguaggi VB e C#, che sono stati potenziati tan-


tissimo con generics e nuove keyword. Una delle mie preferite è
l’istruzione Using, che è sempre stata presente in C# e ora è stata
finalmente aggiunta anche a VB. Questa istruzione è importante
perchè aiuta a scrivere correttamente applicazioni che usano
risorse di sistema e le rilasciano correttamente, permettendo di evitare resource leak.
Direzione Peccato che solo una minoranza di sviluppatori C# la usi correttamente, come ho potuto
Natale Fino (nfino@infomedia.it) notare durante le code review e grazie a qualche domanda mirata nei miei seminari e
Marketing & Advertising conferenze.
Segreteria: 0587/736460
marketing@infomedia.it Passiamo a ClickOnce, che viene presentato come una rivoluzione nel mondo delle
Amministrazione applicazioni Windows. Tutto vero, se non fosse che questa tecnologia è già disponibile
Sara Mattei dalla versione 1.0 di .NET, in forma meno sofisticata ma sufficientemente potente da
(amministrazione@infomedia.it)
poter essere usata in applicazioni reali. Mentre tutti si buttavano sul Web, alcune piccole
Grafica aziende hanno investito su questa tecnologia e hanno sviluppato – in meno tempo e con
Manola Greco (mgreco@infomedia.it) meno spese – applicazioni più potenti e usabili della maggior parte delle applicazioni ASP.
Technical Book NET. Questo è un esempio di come il deficit di conoscenza possa portare a dilatare tempi
Lisa Vanni (book@infomedia.it) e spese di sviluppo, e in definitiva a perdere occasioni commerciali.
Segreteria
Enrica Nassi Il terzo esempio che mi viene in mente è il data binding nelle applicazioni Windows Forms,
(info@infomedia.it) che è stato potenziato in modo considerevole grazie alla introduzione del BindingSource,
un oggetto mediator tra la sorgente dati (es. un DataSet) e i controlli che mostrano i dati
Stampa stessi. Oggetto presentato come una grande innovazione, se non fosse che un oggetto
TIPOLITOGRAFIA PETRUZZI mediator molto simile è disponibile da sempre, sotto il nome di DataView. Per colpa del
Citta’ di Castello (PG) deficit di informazione, molti sviluppatori hanno rinunciato a una tecnologia molto utile
(oppure hanno dovuto complicare il proprio codice all’inverosimile), ancora una volta
Ufficio Abbonamenti allungando inutilmente i tempi di sviluppo.
Tel. 0587/736460 - Fax 0587/732232
e-mail: abbonamenti@infomedia.it
www.infomedia.it
Dove portano queste mie considerazioni? Ovviamente al fatto che la potenza degli strumenti
– i linguaggi, il framework, l’ambiente di sviluppo – vale ben poco se non è accompagnata
Gruppo Editoriale Infomedia srl dalla conoscenza delle possibilità (e dei limiti) delle tecnologie. A questi deficit si può
Via Valdera P., 116 - 56038 Ponsacco (PI) Italia
Tel. 0587/736460 - Fax 0587/732232 supplire solo con la volontà di rimanere sempre aggiornati, leggendo non solo i manuali
red_vbj@infomedia.it “ufficiali” (spesso molto carenti) ma libri, riviste come Visual Basic & .NET Journal, siti
Sito Web www.infomedia.it Internet, blog, e via elencando.
Francesco Balena
fbalena@dotnet2themax.it
Manoscritti e foto originali anche se non pubblicati,
non si restituiscono. È vietata la riproduzione
anche parziale di testi e immagini.

Si prega di inviare i comunicati stampa e gli inviti stampa per


la redazione all’indirizzo: comunicatistampa@infomedia.it
Visual Basic Journal è una rivista di
Gruppo Editoriale Infomedia S.r.l. Via Valdera P, 116 Ponsacco - Pisa.
Registrazione presso il Tribunale di Pisa n. 20/1999
N. 66 - Novembre/Dicembre 2005 VBJ 5
SOMMARIO
NOVEMBRE/DICEMBRE

N.66
SPECIALE
.NET: Delegate e modello di eventi
I delegate, apparentemente strani e complicati, sono in realtà un facile meccanismo per una corretta strutturazione
8
OOP della programmazione ad eventi nel .NET Framework. È importante comprenderne il funzionamento per svilup-
pare corrette applicazioni event-driven.
di Maurizio Mammuccini

TECNICHE
Application e User Settings in Visual Basic 2003 18
di Francesco Balena

APPLICAZIONI

Controllo Remoto in Visual Basic .NET (terza puntata) 28


di Stefano Corti

.NET
Interprocess Communication con MSMQ e .NET Framework 36
Quasi tutte le applicazioni oggigiorno devono comunicare con l’esterno; vediamo un approccio alla comunicazione fra pro-
cessi utilizzando la libreria MSMQ, che permette di scrivere applicazioni sicure e aperte ai futuri sviluppi delle tecnologie
di Carlo Pagliei

La GAC in salsa XML 42


Convertiamo la GAC in un file XML per recuperare velocemente le informazioni su assembly, versioni e namespace

di Filippo Bonanni

SOFTWARE ENGINEERING

Model Driven Architecture 48


Model Driven Architecture (MDA) è il termine con cui OMG identifica il suo tentativo di creare una architettura per
lo sviluppo di applicazioni indipendenti dalla piattaforma
di Lorenzo Vandoni

REPORTAGE
Il nuovo umanesimo tecnologico 52
di Alberto Rosotti

Codice allegato
RUBRICHE
All’indirizzo ftp.infomedia.it/pub/VBJ sono liberamente scaricabili tutti
i listati relativi agli articoli pubblicati. Editoriale 5
La presenza di questa immagine indica l’ulteriore disponibilità, allo
stesso indirizzo, di un progetto software relativo all’articolo in cui
l’immagine è inserita. Il nome identifica la cartella sul sito ftp. .NET Tools 61

N. 66 - Novembre/Dicembre 2005 VBJ 7


PROGRAMMAZIONE AD EVENTI

.NET: Delegate e
modello di eventi
I delegate, apparentemente strani e complicati, sono in realtà un
facile meccanismo per una corretta strutturazione OOP della pro-
grammazione ad eventi nel .NET Framework. È importante com-
prenderne il funzionamento per sviluppare corrette applicazioni
event-driven.

Eventi
di Maurizio Mammuccini

L
a finalità del presente articolo è quella di nalmente una visione organica
trattare sinteticamente gli eventi, i delegate e generale degli argomenti in
ed il modello di eventi del Microsoft .NET modo che poi ogni lettore pos-
Framework, cercando di metterne in evidenza la sa proseguire da solo, utilizzan-
programmabilità OOP e chiarendone i relativi co- doli in modo corretto nelle pro-
strutti formali previsti dalle specifiche. prie applicazioni.
Il modello di eventi di .NET (e i delegate ad esso
strettamente legati) infatti, è stato implementato dal- Perché gli eventi?
la Microsoft aderendo totalmente ed in modo estre-
mamente rigoroso al paradigma OOP e ciò principal- Penso che in ogni esposizione
mente per conseguire due grandi obiettivi di base: che tratti di eventi nelle classi, sia
d’obbligo chiarire cosa un’evento
• rendere più semplice l’utilizzo degli eventi nel- rappresenti per una classe e per-
la fase di progettazione e sviluppo; ché se ne renda necessaria l’intro-
• renderne efficiente e sicura l’esecuzione del relati- duzione nella programmazione.
vo codice (managed code e safe code) a runtime. Una classe non dovrebbe es-
sere solo un pezzo di codice da
Vorrei in questo articolo non soffermarmi sulla utilizzare quando occorre, ben-
sola visualizzazione di uno o due esempi di come sì qualcosa di più organico; una
sia possibile far qualcosa con gli argomenti tratta- classe dovrebbe poter comunica-
ti nelle classi .NET prodotte, bensì fornire addizio- re con l’esterno emettendo noti-
fiche recepibili e comprensibili
da un qualche suo utilizzatore.
Maurizio Mammuccini ha esperienza decennale nella proget- Chiaramente resta da determi-
tazione e sviluppo di software. Dedica particolare attenzione nare cosa, di preciso, la classe
alle tecnologie di calcolo distribuito. Utilizza sin dalle primissime dovrebbe notificare all’esterno. A
versioni il Visual Studio di Microsoft.Attualmente è formatore
e consulente per aziende del settore informatico. È MCSD for
mio avviso il contenuto della no-
VS6 - MCDBA for Sql Server 2000 - MCAD for .NET - MCSD tifica, il suo messaggio, dovrebbe
for .NET ed MCT. Vive e risiede in Umbria. essere legato a quello che i pro-

8 VBJ N. 66 - Novembre/Dicembre 2005


PROGRAMMAZIONE AD EVENTI

gettisti object oriented definiscono come lo sta- Si potrebbe sviluppare un discorso di più
to di un oggetto (scrivo usando il condizionale ampio respiro prevedendo una classe che in-
perché poi nella pratica non sempre è così). capsuli un numero di campi maggiore di uno,
Tramite un evento la classe dovrebbe noti- ad esempio
ficare all’esterno l’avvenuta modifica del suo
stato. C#
Possiamo riguardare lo stato di un oggetto // campi di stato
come l’insieme dei valori in un certo istan- int valueStateInt;
te – nel lifetime dell’oggetto – di tutti i campi string valueStateString
membro della classe che definisce il tipo del-
l’oggetto. VB.NET
È chiaro che la sola modifica di uno di que- ‘campi di stato
sti valori a runtime, porta inevitabilmente al Dim valueStateInt As Integer
cambiamento dello stato dell’oggetto che que- Dim valueStateString As String
sti deve (non è comunque un obbligo) essere
notificato all’esterno tramite un evento. Dal punto di vista della variazione di stato
Spesso questa percezione della realtà di un dell’oggetto non è importante quale valore i
evento ci sfugge perché siamo abituati a pen- campi assumano, ma piuttosto che i valori dei
sare agli eventi come legati esclusivamente al campi (od anche solo uno di questi) varino.
mondo visuale di un’applicazione, ad esempio Questo è motivo sufficiente per sollevare una
la notifica del clic su un bottone in un form notifica al client dell’oggetto, appunto solle-
od in una pagina web; gli eventi in una classe vare un evento.
invece devono avere una giustificazione ben Si potrebbe obiettare che molti eventi solle-
più ampia e concettualmente profonda. vati da oggetti non sempre sorgono corrispon-
dentemente ad una variazione di stato; smon-
Stato di un oggetto tare comunque questa obiezione è semplice.
Chiediamoci primariamente a cosa servano i
Cerchiamo di approfondire il concetto di metodi pubblici di un oggetto, ossia quei me-
stato di un oggetto. Lo facciamo in un caso todi che da client dell’oggetto noi vediamo ed
molto semplice, nel quale la classe che defi- invochiamo. Questi non sono che mezzi per
nisce il tipo dell’oggetto incapsuli un unico manipolare correttamente i dati dall’esterno
campo booleano. (valori dei campi) incapsulati nell’oggetto al-
l’istante di tempo in cui li utilizziamo; in al-
C# tre parole, mezzi per intervenire correttamen-
// campo booleano su cui valutare la variazione te sui valori nei campi incapsulati, ossia sullo
di stato stato dell’oggetto facendo compiere all’ogget-
bool valueState; to qualcosa di utile sui dati.
In questo ragionamento rientrano anche le
VB.NET proprietà esposte dall’oggetto.
‘campo booleano su cui valutare la variazione La classe che definisce il tipo di un oggetto
di stato non dovrebbe fornire funzionalità pubbliche
Dim valueState As Boolean a sé stanti, ossia logicamente scisse dai dati
incapsulati al suo interno. Se ciò avvenisse
L’unico campo che va a determinare lo stato dovrebbe essere in casi del tutto particolari
dell’oggetto è la variabile di tipo booleano value- e sporadici. L’intento è sempre quello di pro-
State e l’evento dovrebbe venir sollevato ogni- gettare tenendo a mente il principio di incap-
qualvolta il valore della variabile passi da Falso sulamento del codice, basilare nella program-
a Vero e viceversa (cambiamento di stato). mazione orientata agli oggetti (OOP).

N. 66 - Novembre/Dicembre 2005 VBJ 9


PROGRAMMAZIONE AD EVENTI

La variazione dello stato di un oggetto deve Dunque ognivolta che nel codice istanziamo
sempre essere accompagnata da una notifica un delegate, non facciamo altro che incapsu-
al client dell’oggetto dell’avvenuta modifica lare in modo sicuro una invocazione ad una
dei valori nei campi al suo interno. opportuna funzione, ossia ad una funzione di
sintassi compatibile a quella dichiarata nel-
Delegate l’istruzione delegate.

Vediamo dunque come .NET ci permetta di C#


costruire queste notifiche di un oggetto e di //istruzione delegate
spedirle al o ai client interessati, addizionan- public delegate int GetIntFromTwoInt(int i, int j);
dole di utili informazioni.
Il fondamento di tutto il modello di even- VB.NET
ti di Microsoft .NET, risiede nell’importante ‘istruzione delegate
concetto di delegate. Public Delegate Function GetIntFromTwoInt(ByVal i
I delegate sono un’eccezionale feature del As Integer, ByVal j As Integer) As Integer
.NET Framework, e rassomigliano vagamen-
te ai puntatori a funzione del C++. Ho scritto
“vagamente” poiché i delegate sono miglio- Le dichiarazioni di delegate precedenti in-
ri dei classici puntatori a funzione del C++, capsulano chiamate a funzioni, invocazioni
essendo type-safe e protetti. ad entità chiamabili, di sintassi compatibile,
Scrivendo type-safe intendiamo che nel C++ ossia che accettano due interi e restituiscono
(non gestito) l’indirizzo di una funzione è soltan- un intero. Ogni altra tipologia di invocazione
to il suo indirizzo in memoria; questo, diversa- non è permessa.
mente dai delegate, è privo di tutto un insieme Da ciò comunque emerge che uno stesso de-
di informazioni addizionali, quali il numero ed legate può essere utilizzato per invocare diffe-
il tipo dei parametri che la funzione prevede, il renti funzioni purchè di identica sintassi.
tipo del valore restituito dalla funzione, la con- Il delegate GetIntFromTwoInt sopra potreb-
venzione di chiamata della funzione. be essere indistintamente utilizzato per invo-
Dichiarare nel codice un tipo Delegate si- care sia una funzione Addizione che Moltipli-
gnifica soprattutto predisporre un tipo deri- cazione di interi, metodi pubblici di una clas-
vato dalla fondamentale classe del .NET Fra- se OperazioniAritmetiche:
mework System.Delegate e contenente il mec-
canismo di chiamata a quella che è detta es- C#
sere un’ entità chiamabile. //Addizione
Cos’è un’entità chiamabile? public int Addizione(int i, int j);
Nel caso di metodi d’istanza possiamo defi- //Moltiplicazione
nire un’entità chiamabile come la coppia data public int Moltiplicazione(int i, int j);
dall’istanza di una classe e da un metodo di
questa; nel caso invece di un metodo statico VB.NET
(static) l’entità chiamabile è data dal nome ‘Addizione
completo (ossia comprensivo del nome della Public Function Addizione(ByVal i As Integer,
classe d’appartenenza) del metodo. ByVal j As Integer) As Integer
Quando viene chiamata un’istanza di dele- ‘Moltiplicazione
gate contenente la chiamata ad una funzione Public Function Moltiplicazione(ByVal i As
che dichiara parametri, sarà poi possibile pas- Integer, ByVal j As Integer) As Integer
sare al delegate gli argomenti attesi in modo
che la funzione venga richiamata con gli in- Il delegato GetIntFromTwoInt sopra non po-
siemi di argomenti definiti. trebbe però venir utilizzato per invocare una

10 VBJ N. 66 - Novembre/Dicembre 2005


PROGRAMMAZIONE AD EVENTI

funzione Opposto di un intero nella classe vengono passati gli argomenti 3 e 4. Questa
OperazioniAritmetiche: è un’impressione errata. Il compilatore, pre-
sa visione che dlg è un delegate, produce il
C# codice necessario all’invocazione del metodo
//Opposto Invoke di dlg.
public int Opposto(int i); Dunque il compilatore, quando compila
l’istruzione di chiamata, la tratta come se con-
VB.NET tenesse esplicitamente l’invocazione al meto-
‘Opposto do Invoke, ossia come se fosse scritta così:
Public Function Opposto(ByVal i As Integer)
As Integer C#
//Invocazione
Per invocare il metodo tramite delegate de- int result = dlg.Invoke(3,4);
v’essere prodotta prima l’istanza del delegate
con indicazione di quale funzione si intenda VB.NET
incapsulare l’invocazione. ‘Invocazione
Dim result As Integer = dlg.Invoke(3,4)
C#
Operazion//Istanziazione della classe del metodo
iAritmetiche oa = new OperazioniAritmetiche(); In C# non è però possibile (a differenza di
//Incapsulamento nel delegate dell’invocazione MC++ ) modificare il codice sorgente in modo
al metodo da invocare esplicitamente la chiamata al me-
GetIntFromTwoInt dlg = new GetIntFromTwoInt todo Invoke trasmettendo gli argomenti per il
(oa.Addizione); metodo incapsulato nel delegate; in tal caso
otterremmo il seguente errore:
VB.NET
‘Istanziazione della classe del metodo [Compiler Error CS1533]
Dim oa As OperazioniAritmetiche = Il metodo Invoke non può essere chiamato
New OperazioniAritmetiche() direttamente su un delegato.
‘Incapsulamento nel delegate dell’invocazione
al metodo Utilizzando l’utility Ildasm.exe fornita dalla
Dim dlg As GetIntFromTwoInt = Microsoft col .NET Framework ed analizzan-
New GetIntFromTwoInt(oa.Addizione) do il codice compilato è possibile entrare un
po’ negli internals del meccanismo di chia-
L’esecuzione della chiamata alla funzione in- mata al metodo e quindi poter comprendere
capsulata avviene semplicemente chiamando meglio cosa succeda dietro le quinte.
il delegate e passandogli gli argomenti Se disassembliamo con Ildasm il compila-
to dell’eseguibile dove i delegate sono stati
C# compilati, troviamo che GetIntFromTwoInt
//Invocazione e GetIntFromOneInt sono stati definiti dal
int result = dlg(3,4); compilatore come classi denominate rispet-
tivamente GetIntFromTwoInt e GetIntFro-
VB.NET mOneInt e derivate dalla fondamentale clas-
‘Invocazione se System.MulticastDelegate del .NET Fra-
Dim result As Integer = dlg(3,4) mework.
Ci può aiutare in questo discorso dare uno
Se osserviamo la sintassi di invocazione al sguardo alla Figura 1 che mostra la struttura
metodo, sembra che dlg sia una funzione a cui della classe scritta nell’assembly.

N. 66 - Novembre/Dicembre 2005 VBJ 11


PROGRAMMAZIONE AD EVENTI

latore abbia inoltre prodot-


to i tre metodi BeginInvo-
ke, Invoke, EndInvoke nel-
le classi di delegate.
La chiamata al metodo In-
voke utilizza i campi priva-
ti _target e _methodPtr per
richiamare il metodo incap-
sulato nel delegate sul parti-
colare oggetto indicato. Per-
tanto la sintassi del metodo
Invoke deve coincidere esat-
tamente con quella indicata
Figura 1 Delegati nel compilato IL per il delegate.
Gli altri due metodi Begi-
nInvoke ed EndInvoke han-
Per il compilatore tutti i delegate (allo stato no invece un’utilizzo nella gestione callback
attuale del .NET Framework) derivano dalla del metodo incapsulato.
classe System.MulticastDelegate ed in defi- Spesso ed erroneamente molti testi od artico-
nitiva dalla classe System.Delegate. li connotano subito il metodo incapsulato nel
Soltanto i compilatori sono istruiti su come delegato come metodo callback (metodo di ri-
derivare dalla Delegate o dalla MulticastDe- chiamata); ciò è vero se il metodo è utilizzato
legate, mentre per i programmatori questo in tal senso tramite l’utilizzo di BeginInvoke
non è consentito. Dunque da codice non ci è ed EndInvoke. Ogni altro utilizzo del delega-
possible derivare queste due classi. te produce soltanto un’invocazione (anonima)
Come si vede dalla Figura 1 tutti i delegate delegata a metodo di un altro oggetto.
presentano un costruttore con due parametri, L’utilizzo callback del metodo incapsulato
un riferimento ad un oggetto ed un tipo intero nel delegate vede l’invocazione a BeginInvo-
che fa riferimento al metodo incapsulato. ke che avvia la chiamata asincrona e ritorna
Questo costruttore riflette un po’ tutta la ge- immediatamente al chiamante senza atten-
rarchia che a partire dalla classe Delegate si dere l’ultimazione della chiamata.
sviluppa sino alla classe di delegato passan- L’esecuzione di EndInvoke viene esegui-
do per la MulticastDelegate. ta per recuperare i risultati della chiamata
Risalendo a ritroso la gerarchia, i valori pas- asincrona e può avvenire in ogni momento
sati ad argomento al costruttore del nostro de- dopo l’invocazione a BeginInvoke.
legate servono ad impostare due campi privati Nel presente articolo non mi soffermo su que-
della classe Delegate; questi campi sono _target sti aspetti di callback, a tale argomento sarebbe
di tipo System.Object (un riferimento all’og- necessario dedicare un articolo ulteriore.
getto su cui si deve eseguire l’invocazione al Qui voglio solo evidenziare che tramite delega
metodo incapsulato) e _methodPtr di tipo Sy- si può utilizzare callback, un metodo di classe,
stem.Int32 (un intero con cui il CLR identifica il cui tempo d’esecuzione potrebbe essere an-
univocamente il metodo da chiamare). che lungo e bloccare il thread che lo invoca.
Tramite le due proprietà Target e Method
(ereditate dalla System.Delegate) la classe Chiamate con associazione tardiva
MulticastDelegate mette a disposizione dei
programmatori la possibilità di leggere i va- Può inoltre essere utile, con alcune impor-
lori dei campi _target e _methodPtr. tanti osservazioni, far vedere come chiamare
Sempre dalla Figura 1 si nota come il compi- con associazione tardiva (late-bound) la fun-

12 VBJ N. 66 - Novembre/Dicembre 2005


PROGRAMMAZIONE AD EVENTI

zione incapsulata nel delegate, passandogli gli ulteriori approfondimenti il lettore può rife-
argomenti come un array di tipo object rirsi all’ottimo manuale di Jeffrey Richter [1]
indicato in bibliografia.
C#
//Invocazione con associazione tardiva .NET Events model
object[] args = new object[2]{3,4};
int result = dlg.DynamicInvoke(args); Il modello di eventi del .NET Framework si
basa su un’idea molto semplice che chiama
VB.NET in causa i delegate. Ossia, il mittente (o sor-
‘Invocazione con associazione tardiva gente) dell’evento non è a conoscenza di qua-
Dim args As Object() = New Object(1) {3, 4} le oggetto (ricevente o destinatario) riceverà
Dim result As Integer = dlg.DynamicInvoke(args) e possibilmente gestirà la notifica prodotta.
L’events model .NET prevede in tal senso di
Val la pena di osservare che durante il bin- dover fornire un intermediario fra l’oggetto
ding al metodo, nelle invocazioni con late bin- mittente e l’oggetto ricevente.
ding, si può subire un certo overhead dovuto Il ruolo d’intermediario viene recitato da un
ai controlli sul metodo (es. numero dei para- apposito delegate detto delegato d’evento .NET
metri, tipo dei parametri, corretta assegnazio- che per convenzione presenta una sua sintas-
ne degli argomenti, …). si standard codificata nel Framework con due
Questo overhead si riduce se non si utiliz- parametri, l’origine che ha generato l’evento
za il late binding al metodo, ossia se invece e i dati trasmessi con la notifica dell’evento.
si sfrutta l’early binding o binding anticipa- Torneremo fra breve sull’importante punto
to al metodo incapsulato nel delegate. Appro- della sintassi del delegato d’evento.
fondiamo questo aspetto. Quindi il delegato d’evento si frappone come
Il metodo Invoke prodotto dal compilatore, oggetto fra i due terminali di comunicazione
come già osservato in precedenza, dentro la e non gestisce direttamente la notifica, quin-
classe compilata del delegate ha sintassi esat- di non deve essere riguardato come riceven-
tamente coincidente con quella del metodo te. Il delegato si ricorda per la precisa notifi-
target incapsulato nel delegate. ca d’evento che riceve, quale oggetto e quale
A questo punto è noto anticipatamente (ear- metodo di quest’ultimo gestirà la comunica-
ly binding) a tempo di compilazione se, pas- zione ricevuta.
sando direttamente tra parentesi gli argomen- Da codice è semplice stabilire il legame tra
ti attesi – subito dopo il nome del reference il mittente ed il delegato d’evento. Vediamo
all’oggetto delegate – sia rispettata o meno la come.
sintassi del metodo target. Il delegato d’evento viene dichiarato nella
Utilizzando invece, nell’invocare il metodo classe del mittente:
target, il metodo DynamicInvoke a tempo di
compilazione, non si ha nessun controllo sul- C#
la sintassi d’assegnazione degli argomenti. //Dichiarazione del delegato d’evento
Infatti come si vede dal codice sopra questi public delegate EventNameEventHandler
vengono passati come semplice array di tipo (object s,EventArgs e)
object e l’assegnazione viene risolta a tempo //Dichiarazione dell’evento
d’esecuzione, ossia con late binding. public event EventNameEventHandler EventName;
L’argomento dei delegate, straordinariamen-
te bello ed interessante, è lungi dall’essere VB.NET
ultimato. Qui non vado oltre e mi limito ora ‘Dichiarazione del delegato d’evento
ad esporne sinteticamente l’applicazione nel Public Delegate Sub EventNameEventHandler(ByVal s
modello ad eventi del .NET Framework. Per As Object, ByVal e As EventArgs)

N. 66 - Novembre/Dicembre 2005 VBJ 13


PROGRAMMAZIONE AD EVENTI

re il codice necessario ad inol-


trare la chiamata del mittente
all’opportuno delegate quando
avviene la notifica verso l’ester-
no. Sin qui però il delegate non
conosce il particolare metodo
che poi dovrà chiamare (han-
dler) quando riceve la notifi-
ca. Questa informazione viene
passata, ed era naturale aspet-
tarselo, nel destinatario finale
Figura 2 IL della classe sorgente d’evento
della notifica d’evento, il qua-
le si registra per ricevere la
notifica.
‘Dichiarazione dell’evento È interessante approfondire come viene im-
Public Event EventName As EventNameEventHandler postata tale informazione.
Ricorriamo ancora una volta al “fedele” Il-
Se, ad esempio, l’evento nella classe Noti- dasm.exe.
fyingClass ha nome StateChange con delegate Dalla Figura 2 osserviamo che disassemblan-
StateChange-EventHandler, si avrà il seguen- do l’assembly della classe sorgente d’evento
te codice di dichiarazione dell’evento: notiamo che l’evento StateChange, dal com-
pilatore, è stato scisso in due funzioni pub-
C# bliche nascoste add_StateChange e remove_
//Dichiarazione del delegato d’evento StateChange.
public delegate StateChangeEventHandler Lo scopo preciso di queste funzioni, che
(object s,EventArgs e) non possiamo invocare esplicitamente e di-
//Dichiarazione dell’evento rettamente, è quello di favorire al ricevente
public event StateChangeEventHandler StateChange; un modo di gestire il carico o lo scarico del-
l’eventuale handler d’evento.
VB.NET Ho scritto che noi non possiamo invocare
‘Dichiarazione del delegato d’evento esplicitamente e direttamente queste due
Public Delegate Sub StateChangeEventHandler funzioni. In realtà lo facciamo in una forma
(ByVal s As Object, ByVal e As EventArgs) particolare che ora evidenzio. Nella classe del
‘Dichiarazione dell’evento ricevente scriviamo:
Public Event StateChange As StateChangeEventHandler
C#
Questo evento solleva una notifica di cam- //Dichiarazione del reference al mittente
biamento di stato ogniqualvolta l’unico cam- MittenteTypeClass reference;
po booleano valueState subisce la trasfor- //Valorizzazione del reference al mittente
mazione da true a false (True a False) e vi- reference=new MittenteTypeClass([<args>]);
ceversa. //Dichiarazione del gestore l’evento
Dal codice scritto si legge esplicitamente il reference.EventName+=new MittenteTypeClass.
collegamento tra la sorgente d’evento ed il de- EventNameEventHandler(
legato che riceve notifica, infatti l’evento è di- reference_EventName
chiarato proprio come il delegato d’evento, a );
significare che quel delegate sarà informato
che è successo qualcosa nel mittente. VB.NET
Questo è sufficiente al compilatore per scrive- ‘ Dichiarazione del reference al mittente

14 VBJ N. 66 - Novembre/Dicembre 2005


PROGRAMMAZIONE AD EVENTI

Dim reference As MittenteTypeClass mente chiamato argomenti d’evento è incap-


‘ Valorizzazione del reference al mittente sulato dentro una classe derivata dalla classe
Reference=New MittenteTypeClass([<args>]) System.EventArgs.
‘ Dichiarazione del gestore l’evento La dichiarazione dunque di una classe d’argo-
AddHandler reference.EventName, AddressOf menti d’evento da passare con la notifica è:
reference_EventName
C#
Dunque, l’utilizzo della funzione add_Event- //Classe d’argomenti d’evento
Name passa in C# per l’operatore +=, mentre public class EventNameEventArgs : System.
in Visual Basic.NET passa per l’utilizzo della EventArgs{…}
funzione AddHandler.
In modo similare, l’utilizzo della funzione re- VB.NET
move_EventName passa in C# per l’operato- ‘ Classe d’argomenti d’evento
re -=, mentre in Visual Basic.NET passa per Public Class EventNameEventArgs
l’utilizzo della funzione RemoveHandler. Inherits System.EventArgs
L’implementazione dell’evento, nell’assem- ‘…
bly, in due funzioni add_XXX e remove_XXX End Class
offre la possibilità al ricevente di gestire una
propria lista interna, di tipo EventHandlerList, Nell’esempio utilizzato nell’articolo possia-
di handler per l’evento andando ad aggiungere mo definire una classe d’argomenti d’evento
od a rimuovere item dalla lista stessa a secon- StateChangeEventArgs che fornisce addizio-
da dell’esigenza o meno di gestire particolari nalmente nella gestione d’evento il vecchio
eventi, o di cambiare a runtime un particolare valore di stato ed il nuovo (Listato 1).
gestore d’evento a favore di un altro. Quando nel mittente viene sollevato l’evento,
la classe StateChangeEventArgs viene istan-
Argomenti d’evento ziata e caricata delle informazioni da trasmet-
tere al ricevente con la notifica:
Concludo l’articolo indicando un’altra im-
portante feature OOP degli eventi, spesso C#
purtroppo sottovalutata dai programmatori: //Valorizzazione degli argomenti
la possibilità di fornire e gestire classi di in- StateChangeEventArgs evArgs = new StateChangeEvent
formazioni con l’evento. Args(oldValoreBooleano, newValoreBooleano);
Se ben ricordiamo, precedentemente ho //Passaggio degli argomenti con la notifica d’evento
scritto che la sintassi del delegato d’evento è this.StateChange(this,evArgs);
pressochè standard. La funzione nel riceven-
te che viene richiamata in gestione (handler) VB.NET
dell’evento notificato ha una sintassi canonica ‘ Valorizzazione degli argomenti
dove, oltre alla sorgente dell’evento, è presen- Dim evArgs As StateChangeEventArgs = New StateChange
te un parametro all’interno del quale si riceve EventArgs(oldValoreBooleano, newValoreBooleano)
con la notifica anche un potenziale insieme di
valori d’informazione, che possono risultare ‘Passaggio degli argomenti con la notifica d’evento
utili per la gestione dell’evento stesso. Me.StateChange(Me,evArgs)
Va detto comunque che non è obbligatorio
associare alla notifica un insieme di valori, Un’osservazione tratta
ma in alcuni casi utilizzare informazioni ad- dal .NET Framework
dizionali potrebbe essere di estremo aiuto alla
routine che gestisce l’evento. La trasmissione di informazioni con la no-
Questo insieme di valori che viene comune- tifica d’evento ha applicazioni già dentro

N. 66 - Novembre/Dicembre 2005 VBJ 15


PROGRAMMAZIONE AD EVENTI

Listato 1 La classe StateChangeEventArgs che fornisce il vecchio il .NET Framework stesso.


e il nuovo valore di stato
Si può, fra le altre, evidenziare
C#
la classe di connessione ad un
//Classe d’argomenti d’evento associata all’evento StateChange database XxxConnection del-
public class StateChangeEventArgs : EventArgs { l’infrastruttura ADO.NET.
/* Questa espone pubblica-
* Vecchio e nuovo valore di stato
*/ mente sempre l’evento Sta-
bool oldStateValue;
bool newStateValue; teChange che viene notificato
public StateChangeEventArgs(bool oldState,bool newState)
ai client ogniqualvolta è mo-
{ dificato lo stato della connes-
//
// TODO: aggiungere qui la logica del costruttore sione fra i diversi valori for-
//
this.oldStateValue=oldState; niti nell’enumerazione Con-
this.newStateValue=newState;
nectionState.
}
Con la notifica dell’evento
/// <summary> di cambiamento di stato del-
/// Valore originale di stato della classe notificante
/// </summary> la connessione viene passata
public bool Original
{ un’istanza di classe d’argomen-
get
{ ti d’evento di nome StateChan-
return this.oldStateValue;
} geEventArgs. Il vecchio ed il
} nuovo valore di connessione
/// <summary> possono essere recuperati (ed
/// Valore corrente di stato della classe notificante
/// </summary> utilizzati) dal gestore della noti-
public bool Current
{ fica rispettivamente tramite le
get
{ due proprietà pubbliche Origi-
return this.newStateValue;
} nalState e CurrentState.
} Tenendo presente quanto è
} stato scritto all’inizio dell’artico-
VB.NET lo, voglio qui ribadire l’estrema
‘ Classe d’argomenti d’evento associata all’evento StateChange
importanza di pensare gli even-
Public Class StateChangedEventArgs
Inherits EventArgs ti come notifiche di cambiamen-
‘ Vecchio e nuovo valore di stato to di stato nella sorgente d’even-
Dim oldStateValue As Boolean to, e quindi di informare sul va-
Dim newStateValue As Boolean
lore di vecchio e nuovo stato. A
Public Sub New(ByVal oldState As Boolean, ByVal newState As Boolean)
tale scopo le classi d’argomen-
Me.oldStateValue = oldState
Me.newStateValue = newState to d’evento giocano un ruolo da
End Sub attori principali e non da sem-
‘ <summary>
plici comparse, proprio perché
‘ Valore originale di stato della classe notificante naturalmente parte integrante
‘ </summary>
Public ReadOnly Property Original() As Boolean della notifica prodotta. Ciò indi-
Get
Return Me.oldStateValue pendentemente dal fatto che il
End Get
End Property ricevente gestisca o meno que-
‘ <summary> ste informazioni quando riceve
‘ Valore corrente di stato della classe notificante la notifica.
‘ </summary>
Public ReadOnly Property Current() As Boolean
Get
Return Me.newStateValue Conclusioni
End Get
End Property
End Class In questo articolo ho cercato
di dare una sistematica sep-

16 VBJ N. 66 - Novembre/Dicembre 2005


PROGRAMMAZIONE AD EVENTI

pur breve e sintetica esposizione dei delega- Classi “mute” seppur utili ed interessanti di-
te e del modello di eventi di Microsoft.NET, ventano di difficile gestione perché non si ha
fornendo osservazioni d’implementazione che modo di sincronizzarsi con loro, in quanto non
ritengo utili per tutti i programmatori .NET richiamano e non notificano nulla all’utilizza-
tore. In un prossimo articolo approfondiremo
il confronto tra il modello ad eventi di.NET e
di COM, con la speranza che ciò riesca utile
Il fondamento di tutto il a tutti quei progettisti e programmatori che
modello di eventi di in tempi recenti sono migrati dalla piattafor-
ma COM a .NET.
Microsoft .NET, risiede
nell’importante concetto Bibliografia
di delegate
[1] Jeffrey Richter - “Microsoft .NET Program-
mazione avanzata”, Mondadori Informa-
tica, 2002
Non ho inteso evidenziare automatismi re-
conditi della piattaforma.NET, bensì stimo- Riferimenti
lare i progettisti e programmatori ad utiliz-
zare gli eventi che spesso mancano nelle [2] http://msdn.microsoft.com/library/default.
classi che progettiamo e realizziamo. Una asp?url=/library/en-us/csref/html/vcrefthe-
classe deve poter comunicare all’esterno il delegatetype.asp
proprio cambiamento di stato e questa av- [3] http://msdn.microsoft.com/library/default.
venuta notifica deve poter essere gestita da asp?url=/library/en-us/csref/html/vcwlke-
chi la riceve. ventstutorial.asp
TECNICHE

Application e
User Setting USER

in Visual Basic 2003


di Francesco Balena

U
na delle novità principali di Visual Basic le impostazioni utente. Le
2005 e C# 2.0 è il supporto per la persi- impostazioni sono caricate al
stenza delle impostazioni del programma, lancio del programma e posso-
a livello di applicazione e a livello utente. Potete no essere anche salvate auto-
trovare maggiori informazioni su questa impor- maticamente al suo termine,
tante feature in [1], ma cercherò di riassumere il semplicemente abilitando una
concetto in poche righe. opzione di progetto.
Visual Studio 2005 fornisce un designer (vedi Fi- Le impostazioni a livello uten-
gura 1) che permette di definire le impostazioni te sono conservate in un file
usate dal programma. Man mano che si definisco- nel folder C:\Documents and
no nuove impostazioni, Visual Studio genera il co- Settings\Username\Local Set-
dice della classe Settings (nel namespace My), che tings\Application Data (sono
espone tali impostazioni sotto forma di proprietà, creati tanti file distinti, uno
in modo che si possa poi accedervi da codice con per ciascun utente) mentre le
una syntassi strong-typed, ad esempio: impostazioni a livello di ap-
plicazione sono conservate nel
Dim filename As String = My.Settings.LastLoadedFile file di configurazione della ap-
plicazione.
In un certo senso, la classe My.Settings assolve
al compito che in passato era riservato alle va- I limiti di My.Settings
riabili globali (tipicamente conservate in un mo-
dulo), con in più il vantaggio di poterle caricare Il meccanismo di Visual Stu-
e salvare su file. dio 2005 è decisamente potente
Le impostazioni possono essere definite a livel- ed elegante, ma non risolve af-
lo di applicazione (ad es. la stringa di connessio- fatto tutti i problemi che si pos-
ne al database) oppure a livello di singolo uten- sono verificare lavorando con le
te (ad es. i colori preferiti o la lista degli ultimi impostazioni di un programma,
file caricati). La differenza principale tra i due ad esempio:
tipi di impostazioni è che le impostazioni a li-
vello di applicazioni sono a sola lettura, mentre a) non è possibile memorizzare
quelle a livello utente sono assegnabili. i valori su altri medium, ad
La classe My.Settings espone anche un me- esempio in un campo di da-
todo Save che salva il valore corrente del- tabase.

18 VBJ N. 66 - Novembre/Dicembre 2005


TECNICHE

Figura 1 Il designer di Visual Studio 2005 permette di definire le impostazioni usate dal programma

b) non è possibile specificare se l’utente è lo- di lavorare con applicazioni data-centriche


cale oppure si tratta di un roaming user (in e vorrei creare dei file di “solution” (concet-
modo che le impostazioni utente siano ri- tualmente simili ai file .sln di Visual Studio)
trovate anche se l’utente esegue il login che conservano informazioni sul gruppo di
da un’altra macchina sulla LAN). documenti aperti in un certo momento, e al-
c) a volte diventa importante modificare via tre informazioni al contorno. Visto che però
codice anche le impostazioni a livello di non è possibile caricare il contenuto del-
applicazione, ma questo è assolutamente le impostazioni utente da un file specifico,
impossibile con la classe My.Settings, a per questo tipo di informazioni occorre un
meno di non scrivere un parser del testo meccanismo differente da quello offerto da
XML del file .config. My.Settings.
d) non esiste una proprietà che restituisce il Insomma, alla fine in molti programmi oc-
nome del file contenente le impostazioni corre comunque implementare un meccani-
a livello utente, quindi ad es. non è sem- smo di persistenza delle variabili globali che è
plice eseguire il backup delle impostazioni più raffinato di quello offerto da My.Settings,
utente, oppure implementare un mecca- sia perchè serve avere maggiore controllo su
nismo di recovery dei valori com’era nel- dove le informazioni sono memorizzate (file,
le precedenti sessioni o ancora migrare le database, registry, ecc.) sia perchè è necessa-
impostazioni su altre macchine. rio poter lavorare con più istanze della clas-
se che espone tali variabili (ad esempio per
Più in generale, dopo un po’ di frequenta- poter fare il merge di opzioni di provenien-
zione con la classe My.Settings ci si rende za differente).
conto che spesso risulta insufficiente per i Per questi motivi, ed altri ancora, alla fine
propri scopi. Ad esempio, spesso mi capita ho deciso di scrivere una serie di classi che

N. 66 - Novembre/Dicembre 2005 VBJ 19


TECNICHE

Listato 2 Le altre due classi UserSettingsBase e ApplicationSettingsBase

‘ ----------------------------------------
‘ Base class for user settings
‘ ----------------------------------------

Public MustInherit Class UserSettingsBase


Inherits SettingsBase

Sub New()
Dim dirName As String = Environment.GetFolderPath( _
Environment.SpecialFolder.LocalApplicationData)
Dim appName As String = [Assembly].GetExecutingAssembly().GetName().Name
SetFilename(Path.Combine(dirName, Path.ChangeExtension(appName, DefaultExtension)))
End Sub
End Class

‘ ----------------------------------------
‘ Base class for Application settings
‘ ----------------------------------------

Public MustInherit Class ApplicationSettingsBase


Inherits SettingsBase

Sub New()
Dim dirName As String = _
AppDomain.CurrentDomain.SetupInformation.ApplicationBase
Dim appName As String = [Assembly].GetExecutingAssembly().GetName().Name
SetFilename(Path.Combine(dirName, Path.ChangeExtension(appName, DefaultExtension)))
End Sub
End Class

potessero risolvere una volta per tutte il pro- vono per individuare le proprietà dei do-
blema della definizione e della persistenza cumenti con cui l’utente sta lavorando in
delle impostazioni globali del programma, sia quel momento.
a livello utente che di applicazione. Il codice
è scritto in VB 2003, quindi può essere usa- Grazie alle classi base che introduco in que-
to con la precedente versione di Visual Ba- sto articolo, il compito dello sviluppatore che
sic, ma il risultato è così flessibile e potente vuole implementare un gruppo di valori si
che sto cominciando ad usarlo anche nei miei riduce a definire una classe che eredita da
progetti VB 2005. una classe base e aggiungere alla nuova clas-
In definitiva, quindi, lo scopo di questo arti- se uno o più campi pubblici (uno per ciascu-
colo è mostrare un meccanismo generalizzato na impostazione). Le classi implementate in
per gestire, salvare, e ricaricare un gruppo di questo modo esporranno quindi i vari meto-
valori di uno dei seguenti tipi: di per salvare e ricaricare da file o da stream
il gruppo di impostazioni e verificare se i va-
• Impostazioni a livello di applicazione, con- lori sono stati modificati. Opzionalmente sarà
divise tra tutti gli utenti della applicazio- anche possibile caricare automaticamente le
ne impostazioni a livello di applicazione o utente
• Impostazioni a livello di utente, specifiche quando parte l’applicazione e salvarli quan-
per un particolare utente do l’applicazione viene chiusa. Notare che il
• Impostazioni a livello di progetto (o di so- meccanismo implementato in questo artico-
luzione), che possono essere salvate e rica- lo funziona solo con le applicazioni Windows
ricate esplicitamente dall'operatore e ser- Form, e non ASP.NET.

20 VBJ N. 66 - Novembre/Dicembre 2005


TECNICHE

Listato 3 Una classe che definisce alcune impostazioni a livello utente se, quindi occorre
copiare i valori dei
campi e delle pro-
Public Class MySettings prietà dalla nuova
Inherits UserSettingsBase
istanza all’oggetto
‘ --------------------------------------------------- “corrente” (ossia
‘ Instance fields and properties
‘ ---------------------------------------------------
quello rappresen-
tato dalla keyword
Public Name As String = “Francesco” Me). Ma la classe
Public ID As Integer
Public RecentDocs() As String base non conosce
Public FormLocation As Point = New Point(0, 0) quali sono i campi
Public FormSize As Size = New Size(100, 200)
che verranno defi-
‘ These fields aren’t persisted niti nelle classi de-
<XmlIgnore()> Public FormTitle As String
<XmlIgnore()> Public TimeStarted As Date
rivate. Per risolve-
re questo problema
‘ --------------------------------------------------- il codice usa reflec-
‘ Static members
‘ --------------------------------------------------- tion per iterare su
tutti i campi e le
‘ The Global instance (optional, but makes usage easier)
Public Shared Global As New MySettings proprietà pubbli-
che di istanza, evi-
‘ This static constructor is needed only to automatically load the Global
tando però di co-
‘ instance the first time it is referenced by the application. If the
‘ application doesn’t use the Global instance or it loads piare gli elemen-
‘ it explicitly, you can omit this static constructor. ti marcati con l’at-
Shared Sub New()
If File.Exists(Global.FileName) Then Global.Load() tributi XmlIgnore,
End Sub perchè questi ele-
End Class
menti non devono
essere salvati o ri-
caricati da file.
La classe SettingsBase Reflection viene usata anche nel metodo Ha-
sChanges per confrontare l’istanza corrente
La classe astratta SettingsBase funge da (Me) con l’oggetto salvato nella variabile pri-
classe base per la classe UserSettingsBa- vata OldSettings, in modo da poter determi-
se (base per le impostazioni utente), la clas- nare se anche solo una delle proprietà è sta-
se ApplicationSettingsBase (base per le ta modificata ed è necessario quindi salvare
impostazioni di applicazione), e le altre clas- l’oggetto su file.
si che volete usare per conservare un grup- Il terzo aspetto interessante della classe Set-
po di variabili che devono essere facilmente tingsBase è la proprietà AutoSave, che se im-
lette e scritte da file. postata a True permette di salvare automa-
Il codice sorgente della classe astratta Set- ticamente su file il contenuto della istanza
tingsBase è lungo (Listato 1), ma il suo fun- quando l’applicazione termina (a condizio-
zionamento è abbastanza lineare. ne ovviamente che l’istanza sia stata carica-
Il meccanismo di persistenza in XML del- ta in precedenza da file o almeno che la sua
la classe è implementato mediante l’oggetto proprietà FileName sia stata assegnata cor-
XmlSerializer, che viene usato nei vari over- rettamente).
load dei metodi Load e Save. Con il metodo Questa feature si basa sull’evento Proces-
Load, però, c’è un piccolo problema da ri- sExit dell’oggetto AppDomain, che scatta ap-
solvere: il metodo Deserialize di XmlSeriali- punto quando il processo corrente sta per ter-
zer restituisce una nuova istanza della clas- minare.

N. 66 - Novembre/Dicembre 2005 VBJ 21


TECNICHE

Le classi UserSettingsBase Creare una classe di impostazioni


e ApplicationSettingsBase utente

Le altre due classi base sono decisamen- A differenza della classe My.Settings di VB
te più semplici. In pratica, esse derivano da 2005, che contiene sia impostazioni utente che
SettingsBase e modificano soltanto il valo- di applicazione, l’approccio che propongo in
re di partenza della proprietà FileName. Nel questo articolo richiede la definizione di due
caso di UserSettingsBase la proprietà punta classi distinte, una per le impostazioni uten-
al file C:\Documents and Settings\Username\ te e una per le impostazioni di applicazio-
Local Settings\Application Data\
Data\Application- ne. Ovviamente, è possibile che uno specifi-
Name.xml, mentre nel caso di ApplicationSet- co progetto richieda impostazioni di un solo
tingsBase la proprietà punta al file Applica- tipo, quindi non è obbligatorio definire sem-
tionName.xml nella stessa directory dell’ap- pre due classi.
plicazione. Grazie alla potenza delle classi base prepa-
Dal sorgente della classe SettingsBase si rate in precedenza, il sorgente di una clas-
può notare che le assegnazioni alla proprie- se per le impostazioni utente è davvero mol-
tà FileName provocano una eccezione se la to semplice. Ecco ad esempio una classe che
classe è del tipo UserSettingsBase o Ap- definisce alcune impostazioni a livello uten-
plicationSettingsBase, quindi il costrutto- te (Listato 3).
re di queste classi usa il metodo Protected Per default tutti i campi e le proprietà pub-
Sub SetFileName per aggirare questo pro- bliche delle classi che derivano da UserSet-
blema. tingsBase sono scritte e lette da file. Acca-
de spesso, d’altra parte, di voler definire
della variabili globali
Listato 4 Una classe che contiene tutte le impostazioni a livello di applicazione che non devono esse-
re persistite tra una
sessione e l’altra.
Public Class MyAppSettings Per ottenere che
Inherits ApplicationSettingsBase
ciò non avvenga, è
‘ --------------------------------------------------- sufficiente marca-
‘ Instance fields and properties
re il campo o la pro-
‘ ---------------------------------------------------
prietà con l’attribu-
Public DatabaseName As String = “SqlServer” to XmlIgnore (vedi
Public MainServer As String = “MYSERVER”
ad es. i campi For-
<XmlIgnore()>Public FormCount As Integer mTitle e TimeStar-
ted nell’esempio pre-
‘ ---------------------------------------------------
‘ Static members cedente.)
‘ --------------------------------------------------- La prima parte del-
la classe MySettings
‘ The Global instance (optional, but makes usage easier)
Public Shared Global As New MySettings cambia da progetto a
progetto, mentre la
‘ This static constructor is needed only to automatically load the Global
‘ instance the first time it is referenced by the application. If the
seconda parte (nel-
‘ application doesn’t use the Global instance or it loads la sezione “Static
‘ it explicitly, you can omit this static constructor. members”) è identi-
Shared Sub New()
If File.Exists(Global.FileName) Then Global.Load() ca per tutte le clas-
End Sub si che derivano da
End Class
UserSettingsBase.
Purtroppo, le rego-

22 VBJ N. 66 - Novembre/Dicembre 2005


TECNICHE

le della ereditarietà non permettono di spo- re un campo readonly in una classe di que-
stare questi membri statici nella classe base. sto tipo).
Comunque, sia il campo Global che il co-
struttore statico sono opzionali, nel senso MySettings.Global.FormSize = New Size(10, 200)
che la classe può funzionare anche se que-
sti membri non sono definiti, come spiega- Ovviamente, i campi e le proprietà readonly
no i commenti. non sono salvate su file.
Esistono due modi per effettuare il salvatag-
gio delle impostazioni utente: esplicitamen-
te mediante il metodo Save oppure implicita-
La classe My.Settings mente mediante la proprietà AutoSave.
Nel secondo caso l’istanza di MySettings
espone anche un è salvata automaticamente (se vi sono sta-
metodo Save che salva te delle modifiche) al termine della appli-
cazione:
il valore corrente delle
impostazioni utente ‘ Salvataggio esplicito sul file di default
MySettings.Global.Save()

‘ Attiva l’auto save


MySettings.Global.AutoSave = True
A questo punto potete definire nuove istan-
ze di MySettings come fareste con qualsiasi La classe MySettings eredita da UserSettin-
altra classe, ma nella maggior parte dei casi gs due ulteriori metodi. Il metodo Refresh ri-
sarà sufficiente usare l’istanza globale sta- pristina il contenuto delle variabili com’era
tic rappresentata dal campo Global. Grazie al momento dal caricamento o salvataggio
al costruttore statico, non è neanche neces- più recente, mentre il metodo HasChanges
sario caricare esplicitamente l’istanza Glo- restituisce True se uno o più campi o pro-
bal alla partenza della applicazione, poiché prietà sono state modificate dopo l’ultimo
tale caricamento avverrà automaticamen- caricamento o salvataggio. In questo modo
te la prima volta che la classe MySettings è è possibile salvare i dati solo se strettamen-
referenziata: te necessario:

Private Sub Form1_Load(ByVal sender As Object, If MySettings.Global.HasChanges Then


ByVal e As EventArgs) Handles MyBase.Load MySettings.Global.Save()
Me.Size = MySettings.Global.FormSize
Me.Location = MySettings.Global.FormLocation Creare una classe di impostazioni di
lblMessage.Text = “Welcome, “ & applicazione
MySettings.Global.Name
Il meccanismo per creare una classe che
‘ Crea nuovi elementi per l’array RecentDocs contiene tutte le impostazioni a livello di
ReDim MySettings.Global.RecentDocs(9) applicazione è identico a quello visto per le
End Sub impostazioni utente, con la sola differenza
che la classe deve ereditare da Application-
Tutti i campi e le proprietà della classe SettingsBase (anziché UserSettingsBase). Un
MySettings sono anche assegnabili, a meno esempio di classe di questo tipo è riportata
che non siano marcati con la parola chiave nel Listato 4.
ReadOnly (ma non ha molto senso inseri- Valgono per la classe MyAppSettings tut-

N. 66 - Novembre/Dicembre 2005 VBJ 23


TECNICHE

ti i commenti fatti per MySettings, inclusa quanto visto in precedenza è che la classe de-
la possibilità di marcare campi e proprietà riva direttamente da SettingsBase e che non
con l’attributo XmlIgnore. La classe MyAp- è necessario un costruttore statico:
pSettings si usa allo stesso modo:
Public Class MyProjectSettings
‘ Leggi una proprietà Inherits SettingsBase
lblServer.Text = “Connecting to “ &
MyAppSettings.Global.DatabaseName Public Documents() As String
Public StartupDocument As String
A differenza delle impostazioni di applica- ‘ altri campi e proprietà
zione di VB 2005, i campi e le proprietà di ‘ ....
MyAppSettings possono essere assegnate e
l’istanza intera può essere salvata sul file di ‘ The Global instance (optional, but makes
default: usage easier)
Public Shared Global As New MyProjectSettings()
‘ Salvataggio esplicito sul file di default End Class
MySettings.Global.Save()
In questo caso non serve definire un co-
Ovviamente, tocca al programmatore il struttore statico, perchè la proprietà File-
compito di accertarsi che un utente possa Name non ha un valore di default inizia-
sovrascrivere le modifiche fatte da un altro le, come accade per le impostazioni utente
utente. Nella pratica, questa feature dovreb- e di applicazione. Per questo motivo, una
be essere abilitata soltanto per gli utenti istanza di MyProjectSettings si carica con
con i privilegi di amministratore, che pos- un overload del metodo Load che accetta
sono quindi influire sulle modalità con cui un argomento (o in alternativa, con il me-
altri utenti usufruiscono della applicazio- todo Load senza argomenti, ma solo dopo
ne stessa. aver assegnato una valore non nullo alla
In confronto, l’approccio imposto da Visual proprietà Filename)
Studio 2005 richiede che l’amministratore mo-
difichi manualmente il file di configurazione, ‘ Leggi una proprietà
quindi direi che la mia tecnica è sicuramente Dim startDoc As String = MyProject
più user friendly. Settings.Global.StartupDocument

Impostazioni di progetto o soluzione ‘ Assegna una proprietà


MyProjectSettings.Global.Documents(0) =
In precedenza accennavo al fatto che spes- “c:\mydoc.txt”
so occorre salvare e ricaricare un gruppo di
variabili che non sono legate nè alla applica- ‘ Salva (1° metodo)
zione nel suo complesso nè al singolo uten- MyProjectSettings.Global.Save
te. Per immaginare come questo possa esse- (“c:\mysettings.xml”)
re utile, basti pensare ai file .sln o .vbproj che
crea Visual Studio per immagazzinare i dati ‘ Salva (2° metodo)
di un progetto o soluzione VB.NET. Questi MyProjectSettings.Global.FileName =
file di soluzione sono poi utilizzabili da più “c:\mysettings.xml”
utenti, possono essere spostati facilmente su MyProjectSettings.Global.Save()
un’altra macchina, ecc.
Definire una classe di questo tipo è davvero Anche in questo caso è possible impostare
semplice. Le uniche due differenze rispetto a a True la proprietà AutoSave, in modo che il

24 VBJ N. 66 - Novembre/Dicembre 2005


TECNICHE

valore sia salvato automaticamente all’uscita tionSettingsBase è abbastanza evidente: esse


della applicazione, anche se in genere il salva- forniscono tutta la flessibilità dell’oggetto
taggio delle impostazioni di progetto dovreb- My.Settings senza dover passare a .NET 2.0,
be essere fatto soltanto dopo aver chiesto al- e anzi otteniamo anche qualcosa in più, in
l’utente se le impostazini correnti devono es- particolare la possibilità di caricare e salvare
sere effettivamente salvate. le impostazioni da qualsiasi file o stream, e la
possibilità di modificare anche le impostazioni
Alternative alla istanza Global di applicazione.
Certo, Visual Studio 2005 permette di defini-
Se si preferisce non usare l’istanza static re la classe Settings in modo visuale, usando
Global occorre definire una variabile che sia l’apposito designer, però mi chiedo se davvero
visibile dall’intero progetto, ad esempio una questo approccio visuale sia meglio che non
variabile Public in un modulo oppure una va- scrivere una classe che contiene tutti i cam-
riabile Shared in una classe o nel form prin- pi che ci interessano. Anzi, direi che prefe-
cipale. In questo caso è possibile eliminare risco di gran lunga l’uso di una classe scrit-
il codice nella sezione “Static Members”, ma ta ad hoc, su cui ho certamente un control-
diventa necessario caricare esplicitamente la lo maggiore.
variabile globale in questione:

Public Module MainModule


Il meccanismo
‘ L’istanza globale usata in tutta
di persistenza in XML
l’applicazione
Public MySettings As New MySettings della classe
è implementato
Sub Main()
‘ Caricamento esplicito
mediante l’oggetto
MySettings.Load() XmlSerializer
MsgBox(“Welcome, “ & MySettings.Name)
‘ ...(continua)
End Sub
End Module Il limite principale di questa versione del-
la classe ApplicationSettingsBase è che le
Il vantaggio di questo modo alternativo di impostazioni sono salvate in un file XML di-
usare MySettings è che i campi e le proprietà stinto dal file di configurazione “ufficiale”
si raggiungono con un solo “punto” anzichè della applicazione. Con un po’ di sforzo in
due (ad es. MySettings.Name anzichè MySet- più questo problema potrebbe essere risol-
tings.Global.Name). to, anzi se lo risolvete mandatemi pure il vo-
stro codice.
Questo meccanismo vale ovviamente anche Un altro limite, un po’ più serio, è che alcu-
per le classi di impostazioni di applicazione ni oggetti non possono essere serializzati in
(derivate da AppSettingsBase) e di soluzione XML. In particolare, gli oggetti che non han-
(derivate direttamente da SettingsBase). no un costruttore senza argomenti e che le
cui proprietà sono a sola lettura hanno que-
Vantaggi e limiti sto problema.
Tra i tipi che soffrono di questo problema, i
Il vantaggio della tecnica basata sulle clas- più comuni sono System.Drawing.Color e Sy-
si SettingsBase, UserSettingsBase e Applica- stem.Drawing.Font: se provate a definire una

N. 66 - Novembre/Dicembre 2005 VBJ 25


TECNICHE

proprietà di questo tipo, nel file XML va a fi- ‘ Altri campi e proprietà


nire un elemento senza contenuto: ‘ ...
End Class
Public Class MySettings
Inherits UserSettingsBase Public Structure ColorXml

Public ForeColor As Color = Color.Blue Public A As Byte


Public R As Byte
End Class Public G As Byte
Public B As Byte
Un modo poco elegante ma efficace per ri-
solvere questo problema è marcare l’elemento <XmlIgnore()> _
con l’attributo XmlIgnore e definire una pro- Public Property Color() As Color
prietà pubblica che provvede alla serializza- Get
zione del valore in formato stringa. Ecco un Return Color.FromArgb(A, R, G, B)
esempio: End Get
Set(ByVal Value As Color)
Public Class MySettings A = Value.A
Inherits UserSettingsBase R = Value.R
G = Value.G
<XmlIgnore()> _ B = Value.B
Public ForeColor As Color = Color.Blue End Set
End Property
Public Property ForeColorText() As String End Structure
Get
Return String.Format(“{0},{1},{2},{3}”, Il codice nella applicazione può usare la pro-
ForeColor.A, ForeColor.R, prietà BackColor come segue:
ForeColor.G, ForeColor.B)
End Get MySettings.Global.BackColor.Color =
Set(ByVal Value As String) New ColorXml(Color.White)
Dim parts() As String = Value.Split(“,”c)
ForeColor = Color.FromArgb(CInt(parts(0)), Il vantaggio di usare una struttura anzichè
CInt(parts(1)), CInt(parts(2)), CInt(parts(3))) una classe per ColorXml è duplice: prima di
End Set tutto non occorre ricordare di usare l’opera-
End Property tore New quando si definisce un elemento di
End Class questo tipo nella classe MySettings. Secon-
do, e più importante, tutte le strutture ridefi-
Se la classe MySettings contiene numero- niscono il metodo Equals per restituire True
se proprietà di un certo tipo non serializza- solo se tutti gli elementi di due strutture coin-
bile, allora può convenire definire una clas- cidono. In questo modo il metodo HasChan-
se accessoria il cui unico scopo è permettere ges definito in SettingsBase continua a fun-
la serializzazione del tipo in questione. Ecco zionare bene anche se la classe MySettings
un esempio: contiene elementi di tipo struttura.

Public Class MySettings Bibliografia


Inherits UserSettingsBase
[1] http://msdn.microsoft.com/library/en-us/
Public BackColor As ColorXml dnvs05/html/vbmysettings.asp

26 VBJ N. 66 - Novembre/Dicembre 2005


APPLICAZIONI

Controllo Remoto
in Visual Basic .NET
Terza puntata
di Stefano Corti

I
n questa terza parte del nostro progetto di Con- boolean che chiameremo flagD e
trollo Remoto in Visual Basic .NET ci occupe- impostiamo tale variabile a True.
remo della progettazione ed implementazione Se il metodo statico Exists() re-
del codice della classe RemoteProcesses. Mediante le stituisce True, significa che la Di-
proprietà e i metodi pubblici che definiremo, sarà rectory specificata è già presen-
possibile eseguire operazioni come creare nuove te nella macchina remota, altri-
cartelle sulla macchina remota, avviare, controllare menti dovrà essere creata invo-
e monitorare i processi in esecuzione, stampare de- cando il metodo statico create-
terminate tipologie di file utilizzando la stampante Directory, passando come argo-
remota ed infine impartire comandi DOS median- mento il valore stringa della va-
te un’interfaccia del tutto simile al Prompt dei Co- riabile path. Le righe di codice
mandi di Windows (cmd.exe). Si tratta quindi di una seguenti vengono eseguite solo
classe abbastanza complessa che, per ragioni che tra a condizione che la variabile di
breve illustreremo, dovrà ereditare anche proprietà tipo boolean flagD abbia assun-
e metodi precedentemente definiti nella classe Re- to il valore True, ovvero soltan-
moteStructure, di cui abbiamo parlato nella prece- to nel caso che sia stata effettiva-
dente puntata. La nostra nuova classe prevede in- mente creata la nuova nuova Di-
vece un semplice metodo costruttore, una proprietà rectory. In tale condizione, prov-
pubblica, dieci metodi pubblici e due metodi priva- vediamo subito ad individuare la
ti. Incominciamo subito ad illustrare il primo me- posizione dell’ultimo carattere \
todo createNewDir(), che oltre a fornirci immedia- (backslash) presente nella strin-
tamente l’occasione per un primo cenno sul mec- ga path. Questo ci consente (me-
canismo dell’ereditarietà, ci consente di creare una diante la funzione di Visual Ba-
nuova Directory su Target. Osserviamo nel Listato sic Left) di ottenere una nuova
1 che il percorso completo della nuova Directory vie- stringa contenente un numero
ne passato al metodo per valore mediante la strin- di caratteri specificato scorren-
ga path. Sarà dunque necessario verificare se la Di- do la stringa a partire dall’estre-
rectory specificata non sia attualmente già presente ma sinistra. In questo contesto,
sulla macchina Target. Creiamo una variabile di tipo otteniamo quindi la Directory di
livello superiore che conterrà la
nostra nuova Directory appena
Stefano Corti si occupa di programmazione PHP e JSP creata, unitamente ad altre car-
lato server, della piattaforma .NET e di integrazione di telle e file eventualmente pre-
sistemi legacy con le nuove realtà del web, soprattutto in
ambito gestionale, bancario e finanziario. È attualmente alle
senti. Mediante la parola chiave
dipendenze di un primario gruppo bancario italiano. Può MyBase, possiamo assegnare il
essere contattato via email: scorti@infomedia.it. valore stringa alla proprietà Pro-

28 VBJ N. 66 - Novembre/Dicembre 2005


APPLICAZIONI

file precedentemente definita all’interno del- Ovviamente dobbiamo anche definire il codi-
la classe RemoteStructure che risulta essere, ce preposto all’intercettazione del relativo co-
in definitiva, la classe “genitore” della classe mando proveniente dall’applicativo Controller,
RemoteProcesses, essendo le due classi legate unitamente al parametro ad esso associato.
attraverso l’istruzione Inherits, che consente
alla classe o interfaccia corrente di ereditare Case Is = “MAKEDIR”
gli attributi, i campi, le proprietà, i metodi e writer.Write(objProc.createNewDir(job(1)))
gli eventi da un’altra classe o interfaccia. Nel- sentText.Clear()
lo stesso modo invochiamo anche il metodo sentText.Text = “Creazione di Directory su
getFilesAndDirectories() per ottenere tutto il Dischi Logici”
contenuto della Directory superiore.
Iniziamo ora a prendere confidenza con le
Imports System classi del .NET Framework che ci consentono
Imports System.IO di avviare, monitorare ed arrestare i processi e
Imports System.Diagnostics le applicazioni in esecuzione. La classe Process
espone un elevato numero di membri per con-
Public Class RemoteProcesses trollare i processi in esecuzione sulle relative
Inherits RemoteStructure macchine. Esamineremo poco per volta queste
... funzionalità, ricordando che tale classe appar-
Sub New() tiene allo spazio dei nomi System.Diagnostics
Me.mProc = “IExplore” che dovrà quindi essere importato nel nostro
End Sub progetto, mediante l’istruzione Imports nelle
prime linee di codice della classe.
Listato 1 Creazione di nuove cartelle su Target Passiamo subito ad un esempio
concreto. Poniamo il caso che nel-
la scheda File Manager nella GUI
Public Function createNewDir(ByVal path As String) As Controller venga selezionato nel
String
ListView remoto un determinato
Dim dirReturn As String file e poi venga premuto il pulsan-
Dim flagD As Boolean = True
te ‘Avvia File Selezionato’. Questo
If Directory.Exists(path) = True Then evento viene intercettato e gesti-
dirReturn &= vbCrLf & “Attenzione: la Directory esiste già...”
Else
to dal codice presente nel Lista-
Try to 2. Al relativo comando START-
Directory.CreateDirectory(path) SELECTEDFILE viene associato
dirReturn &= vbCrLf & “Directory creata con successo
su PC remoto.” il parametro stringa contenente il
Catch e As Exception percorso completo del file indivi-
dirReturn &= vbCrLf & “Errore: “ & e.Message
flagD = False duato. Le procedure che consen-
End Try tono di estrarre e trasformare in
End If
valore String un determinato ele-
If flagD Then mento presente all’interno di un
Dim found As Integer = 0 ListView, le analizzeremo in det-
found = path.LastIndexOf(“\”)
MyBase.Profile = Left(path, found) & “\” taglio quando ci occuperemo del-
dirReturn &= vbCrLf & “Contenuto attuale directory radice: “ & _ la progettazione delle interfacce
MyBase.getFilesAndDirectories()
End If
utente dei programmi Controller e
Target. Per ora ci basta notare che
Return dirReturn al server viene inviato il comando
End Function definito, unitamente al suo para-
metro associato nelle consuete mo-

N. 66 - Novembre/Dicembre 2005 VBJ 29


APPLICAZIONI

Listato 2 Codice associato alla pressione del pulsante Avvia Processo su Controller

Private Sub startProcByFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)


Handles startProcByFile.Click
Dim messGo As String = “STARTSELECTEDFILE>”
Dim list_x As ListView.SelectedListViewItemCollection
list_x = Me.ListView1.SelectedItems
Dim i_list_x As ListViewItem
For Each i_list_x In list_x
messGo &= i_list_x.Text.ToString()
Next
If (messGo = “STARTSELECTEDFILE>”) Then
MessageBox.Show(“Dovete prima selezionare un file da avviare.”, _
“Messaggio di Errore”, MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
Try
writer.Write(messGo)
inMessages.Clear()
inMessages.Text &= vbCrLf & “Comando Inviato: “ & vbCrLf & _
messGo
Catch exception As SocketException
inMessages.Text &= “Errore di comunicazione con il computer remoto: “ & _
exception.Message & vbCrLf
Catch ex As Exception
inMessages.Text &= “Errore: “ & ex.Message & vbCrLf
End Try
End If
End Sub

dalità. Vediamo adesso come il comando viene ne di file, determinando l’avvio del processo
interpretato e gestito dal server Target. ad esso collegato.
Il codice dei metodi pubblici beginProc() ed
... endProc() sono riportati nel Listato 3, mentre
Private objProc As RemoteProcesses = il codice di implementazione della proprietà
New RemoteProcesses() Applifile è visibile nel Listato 4. Esaminiamo
... ora più in dettaglio queste porzioni di codice.
Case Is = “STARTSELECTEDFILE” Prima di tutto ci occorrono alcune variabili di
objProc.AppliFile = job(1) classe private. Dichiariamo xPro e p come va-
... riabili di tipo Process unitamente alle variabili
writer.Write(objProc.beginProc()) nProc, sProc ed mProc di tipo String. Dichiare-
... remo poi altre variabili che ci serviranno per
ulteriori funzionalità che vedremo in seguito.
Abbiamo istanziato un oggetto (privato) dal- In particolare, per adesso, si presti attenzione
la classe RemoteProcesses e lo abbiamo chia- alle variabili sParam di tipo String (impostata
mato objProc. Nella struttura Select End Se- subito a Nothing) e alle variabili stringa mDe-
lect, abbiamo previsto il caso che il coman- lim, mDelemiter e all’array stringa pJob().
do ricevuto sia appunto STARTSELECTE-
DFILE. Alla proprietà AppliFile passiamo Private xPro, p As Process
il valore dell’array Job(1) che contiene ap- Private oRemoteAll As Process()
punto il percorso completo del file da avvia- Private oEnvi, oS As String
re. Non ci resta ora che invocare il metodo Private oDrives As String
beginProc() per l’oggetto objProc che provo- Private oCurrentEnvironment As String
cherà immediatamente l’avvio dell’applica- Private nProcArray As String
zione associata a quella particolare estensio- Private nProc As String

30 VBJ N. 66 - Novembre/Dicembre 2005


APPLICAZIONI

Private sProc As String stringa privata mProc. Successivamente viene


Private mProc As String verificata la presenza del carattere | all’interno
Private oArrow As String della stringa. Il metodo IndexOf() restituisce il
Private sParam As String = Nothing valore negativo -1 se nella stringa esaminata
Private mDelim As String = “|” non viene individuato il carattere presente nel-
Private pJob As String() = Nothing l’argomento del metodo stesso. In questo caso è
Private mDelimiter As Char() = mDelim.ToCharArray() semplice dedurre che unitamente al nome del-
Private iterator As Integer l’applicativo non è stato passato alcun parame-
tro aggiuntivo oppure è stato specificato il per-
Nella GUI del Controller abbiamo infatti pre- corso assoluto di un file. La variabile privata
visto diverse modalità di accesso ai processi re- sProc, che ritroveremo nei metodi beginProc()
moti. Come abbiamo visto, il modo più sempli- ed endProc(), viene posta uguale a mProc. In
ce per avviare un processo consiste nel selezio- caso contrario verrà determinato l’array pJob()
nare un determinato file nel file manager re- che conterrà in indice 0 il nome del processo
moto e innescare quindi l’avvio dell’applicativo da avviare e in indice 1 il parametro specifica-
associato a quella particolare estensione di file. to. Ovviamente il valore (stringa) di job(0) vie-
Abbiamo previsto inoltre un’altra scheda dove ne passato a sProc. Nel metodo beginProc(), al-
l’utente ha a sua disposizione una serie di cam- l’interno di un blocco Try Catch End Try, viene
pi di testo e controlli più completi. Tale Con- verificato se il valore della variabile privata sPa-
trol Tab è visibile nella Figura 1. Come si può ram è rimasto uguale a Nothing oppure ha subi-
osservare, il Controller può avviare o ter-
minare un’applicazione remota semplice-
Listato 3 Metodi pubblici beginProc ed endProc
mente specificando il nome dell’applica-
zione ed inserendo un eventuale para-
metro. Un semplice esempio potrebbe es- Public Function beginProc()
sere IExplore con parametro http://www.
Try
infomedia.it/. Questo provoca l’avvio im- If sParam Is Nothing Then
mediato del browser Internet Explorer xPro = Process.Start(sProc)
Return vbCrLf & “Processo avviato...” & _
su Target e il recupero della URL spe- vbCrLf & “Processo attualmente in corso.”
cificata. Il parametro che il Controller
invierà a Target sarà dunque, nel caso Else
xPro = Process.Start(sProc, sParam)
dell’esempio di cui sopra, strutturato in Return vbCrLf & “Applicazione avviata...” & _
questo modo: LAUNCH>IExplore|http:// vbCrLf & “Processo attualmente in corso.”
www.infomedia.it/. In pratica, nel codi- End If
ce che gestisce l’evento associato al pul- Catch e As Exception
Return vbCrLf & “Errore: “ & e.Message
sante premuto, viene ricostruita la strin-
End Try
ga per mezzo delle righe riportate nel Li-
stato 5. Vediamo ora come tutto questo End Function

viene gestito a livello Target. Public Function endProc()


Osserviamo ancora una volta il Listato Try
xPro.CloseMainWindow()
4. Abbiamo visto che il parametro invia- xPro.Close()
to deve essere ulteriormente splittato in Return vbCrLf & “Processo chiuso...” & _
due parti per estrarre il nome del proces- vbCrLf & “Applicazione attualmente chiusa.”
Catch e As Exception
so da avviare e il relativo parametro. Le Return vbCrLf & “Errore Intercettato: “ &
due porzioni sono divise da un carattere e.Message
End Try
separatore (| carattere pipe). Prima di tut-
to vediamo che il valore passato alla pro- End Function
prietà viene memorizzato nella variabile

N. 66 - Novembre/Dicembre 2005 VBJ 31


APPLICAZIONI

Listato 4 Proprietà AppliFile della classe Remote alla corrispondente finestra principale e resti-
Processes tuisce il valore Boolean True se il messaggio è
stato inviato correttamente, False se il proces-
Public Property AppliFile() As String so associato non dispone di una finestra prin-
Get
Return mProc cipale o se la finestra principale è disattivata.
End Get Successivamente il metodo Close() libera tutte
Set(ByVal Value As String)
mProc = Value le risorse associate al componente.
If (mProc.IndexOf(mDelim) = -1) Then Vediamo ora come implementare un servizio
sProc = mProc
completo che consente di impartire, in un’ap-
Else
pJob = mProc.Split(mDelimiter, 2) posita scheda dell’interfaccia Controller del
sProc = pJob(0) tutto simile al Prompt dei Comandi di Win-
sParam = pJob(1)
End If dows XP, qualsiasi comando DOS e fare in
End Set modo che questo comando venga eseguito su
End Property
Target, ottenendo infine il relativo output. Con
determinati metodi di alcune importanti classi
to cambiamenti. Nel primo caso, viene invocato del .NET framework, tutto questo può essere
il metodo Start() della classe Process, passando progettato e realizzato con estrema semplicità.
come argomento il valore di sProc, che conterrà Definiamo dunque il metodo pubblico promp-
il nome dell’applicazione da avviare oppure il tInputOutput(), il cui codice è visibile nel Li-
percorso completo del file da eseguire. Si tratta stato 6. Dobbiamo anzitutto creare un nuovo
di un metodo di overload che, se viene determi- componente Process che, in questo caso, chia-
nato un solo valore String, avvia una risorsa di meremo myPdos. Successivamente occorre uti-
processo, specificando il nome di un documen- lizzare la proprietà StartInfo che rappresenta
to o un file di applicazione e associa la risorsa l’insieme di parametri che servono per avvia-
a un nuovo componente Process. Diversamen- re un processo, impostando quindi le proprietà
te (vedi codice dopo la Else) il metodo accetta da passare al metodo Start() del componente
anche due parametri sempre di tipo String, in- Process. La seguente proprietà FileName è di
nescando l’avvio di una risorsa di processo (in fatto l’unico membro necessario di StartInfo,
questo caso viene specificato
il nome di un’applicazione e
un insieme di argomenti del-
la riga di comando) e associa
la risorsa ad un nuovo compo-
nente Process. All’interno del
metodo endProc() vengono in-
vocati invece i metodi pubblici
CloseMainWindow() e Close().
La chiamata di questi metodi
è relativa a xPro, che abbia-
mo visto essere di tipo Pro-
cess a cui è stata appena asso-
ciata la risorsa corrispondente
al processo precedentemen-
te avviato. Più precisamente,
CloseMainWindow() chiude
un processo che dispone di
un’interfaccia utente invian- Figura 1 Scheda contenente i controlli dei Processi nella GUI del Controller
do un messaggio di chiusura

32 VBJ N. 66 - Novembre/Dicembre 2005


APPLICAZIONI

Listato 5 Evento associato alla richiesta di avvio processo con parametro

Private Sub startProcButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)


Handles startProcButton.Click
If (txtStartProc.Text = “” Or txtStartProc.Text Is Nothing) Then
MessageBox.Show(“Dovete specificare un processo oppure il percorso di un file da lanciare.”, _
“Messaggio di Errore”, MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
Dim messGo As String
If (txtStartParam.Text = “” Or txtStartParam.Text Is Nothing) Then
messGo = “LAUNCH>” & txtStartProc.Text
Else
messGo = “LAUNCH>” & txtStartProc.Text & “|” & txtStartParam.Text
End If
Try
writer.Write(messGo)
inMessages.Clear()
inMessages.Text &= vbCrLf & “Comando Inviato: “ & vbCrLf & _
messGo
Catch exception As SocketException
inMessages.Text &= “Errore di comunicazione con il computer remoto: “ & _
exception.Message & vbCrLf
Catch ex As Exception
inMessages.Text &= “Errore: “ & ex.Message & vbCrLf
End Try
End If
End Sub

laddove l’avvio di un processo mediante spe- un valore che indica se l’input di comando del
cifica della proprietà FileName è analogo alla processo deve essere letto dal membro Stan-
digitazione delle informazioni nella finestra di dardInput dell’istanza di Process, consenten-
dialogo Esegui del menu di avvio di Windows. do in tal modo la lettura dei dati da un’origi-
In questo caso il nome del file da specificare ne diversa dal flusso di input standard. Redi-
non può che essere l’eseguibile .exe che atti- rectStandardOutput opera in modo del tutto
va il prompt dei comandi, ovvero cmd.exe. Im- analogo per i dati in uscita dal processo, pro-
postiamo quindi la proprietà CreateNoWindow vocando la scrittura del flusso su una destina-
su True, al fine di non determinare la compar- zione differente dal flusso di output standard
sa della finestra GUI sulla macchina Target, che abbiamo visto essere, nella quasi totalità
quando invocheremo il metodo Start(). Le suc- dei casi, lo schermo del PC.
cessive tre proprietà richiedono più attenzio- Prima di potere utilizzare queste proprie-
ne. Quando un processo viene avviato, suppo- tà, è necessario impostare la proprietà Use-
niamo un eseguibile come appunto cmd.exe, ShellExecute su True, poiché è indispensabi-
i canali di input predefiniti sono in genere la le segnalare al CLR del .NET framework che
tastiera o eventualmente periferiche di pun- non intendiamo utilizzare la shell del sistema
tamento quali il mouse, mentre il canale di operativo per avviare il processo, bensì inten-
output principale è quasi sempre lo schermo diamo creare il processo direttamente dal file
collegato alla macchina sulla quale il processo eseguibile. L’impostazione di questa proprietà
è in esecuzione. Per ottenere la remotizzazio- su False consente di reindirizzare i flussi di
ne di un processo è necessario variare o me- input, output e di errore. Impostiamo quindi
glio reindirizzare i flussi di input/output verso le proprietà RedirectStandardInput e Redi-
il processo medesimo. Le proprietà Redirect- rectStandardOutput su True. Ora che abbia-
StandardInput e RedirectStandardOutput si mo ottenuto il reindirizzamento dei canali di
occupano proprio di questo specifico aspetto. I/O, dobbiamo innescare l’avvio del processo
In particolare, RedirectStandardInput imposta mediante la chiamata del metodo Start() e vei-

N. 66 - Novembre/Dicembre 2005 VBJ 33


APPLICAZIONI

Listato 6 Remotizzazione del Prompt dei Comandi DOS scrivere e leggere dati dell’applicazio-
ne. Ricordiamo che queste proprietà
Public Function promptInputOutput(ByVal ooPP_dos As
ritornano valori di tipo StreamWriter e
String) As String StreamReader, quindi dobbiamo anzitut-
Dim DOS_report_output As String = Nothing to creare una prima istanza della clas-
Dim myPdos As New Process()
se StreamWriter che chiameremo DOS_
myPdos.StartInfo.FileName = “cmd.exe” sss a cui verrà passato il valore (di tipo
myPdos.StartInfo.CreateNoWindow = True
myPdos.StartInfo.UseShellExecute = False StreamWriter) restituito dalla proprietà
myPdos.StartInfo.RedirectStandardInput = True StandardInput dell’oggetto myPdos di
myPdos.StartInfo.RedirectStandardOutput = True
myPdos.Start()
tipo Process. Le classi StreamWriter e
StreamReader gestiscono l’input e l’ou-
Dim DOS_sss As StreamWriter = myPdos.StandardInput tput di caratteri in una particolare codi-
DOS_sss.WriteLine(ooPP_dos)
DOS_sss.Close() fica (in genere UTF8 Encoding, se non
DOS_report_output = myPdos.StandardOutput.ReadToEnd() diversamente specificato) e differisco-
myPdos.WaitForExit()
myPdos.Close() no sostanzialmente dalle classi deriva-
te da Stream che gestiscono invece le
Return “DOSPROMPTREPLY>” & DOS_report_output
operazioni di I/O a livello di byte. Ab-
End Function biamo così ottenuto l’oggetto DOS_sss
per il quale invochiamo il metodo Wri-
teLine() (ereditato da TextWriter) che si
colare i dati in transito. Il metodo che stiamo occupa della scrittura dei dati, come previsto
realizzando accetta in ingresso valori di tipo dai parametri di overload, seguiti da un termi-
String passati per valore alla variabile strin- natore di riga. Il valore stringa passato al me-
ga ooPP_dos. Chiaramente ooPP_dos assume- todo non è altro che il contenuto della variabi-
rà il valore di job(1) il quanto il metodo verrà le ooPP_dos. Invochiamo quindi il metodo clo-
invocato nella struttura Select Case EndSelect se() per determinare la chiusura del flusso. Ora
all’interno del ciclo principale del server con- che abbiamo inviato il comando al processo,
tenuto nella classe Form1. dobbiamo immediatamente estrarne l’output
opportunamente reindirizzato. Inizializziamo
Case Is = “GETDOSPROMPT” una variabile stringa DOS_report_output e le
Try assegniamo subito il valore restituito dal meto-
sentText.Clear() do ReadToEnd() invocato per l’oggetto di tipo
sentText.Text = “ESECUZIONE CMD.EXE” & StreamReader ritornato dalla proprietà Stan-
vbCrLf & job(1) dardOutput di myPdos. Il metodo sovraccari-
writer.Write(objProc.promptInputOutput(job(1))) co WaitForExit() che invochiamo subito dopo
Catch exception As SocketException la chiamata di ReadToEnd() è molto importan-
sentText.Clear() te in quanto indica al componente Process di
sentText.Text = “Errore di Comunicazione: “ & attendere in modo indefinito la terminazione
exception.Message & _ del processo associato, al fine di consentire al
vbCrLf thread corrente di attendere che tale processo
Catch ed As Exception venga terminato. Infine il metodo Close() libera
sentText.Clear() la memoria allocata al processo terminato.
sentText.Text = “Errore: “ & ed.Message & vbCrLf
End Try Conclusioni
Nel prossimo appuntamento completeremo
A questo punto dobbiamo utilizzare le pro- la trattazione di questa importante classe e
prietà StandardInput e StardardOutput che realizzeremo un completo sistema di chat te-
ottengono flussi utilizzati rispettivamente per stuale tra Controller e Target.

34 VBJ N. 66 - Novembre/Dicembre 2005


.NET

Interprocess Communication
con MSMQ e .NET
Quasi tutte le applicazioni oggigiorno devono comunicare con l’ester-
no; vediamo un approccio alla comunicazione fra processi utilizzan-
do la libreria MSMQ, che permette di scrivere applicazioni sicure e
MSMQ
aperte ai futuri sviluppi delle tecnologie

di Carlo Pagliei

E
sistono molti modi per far comunicare fra In questo articolo analizzeremo
loro due o più applicazioni: il modo classi- gli aspetti principali di Micro-
co è quello di definire un protocollo per lo soft Message Queue (MSMQ),
scambio dei dati e un tipo di trasporto. Ad esempio facendo in particolare riferimen-
potremmo utilizzare una socket TCP come trasporto to alla libreria System.Messa-
e il protocollo HTTP o FTP, oppure una porta seria- ging del .NET Framework, ne
le con un protocollo proprietario creato ad-hoc. Esi- vedremo un’applicazione pra-
stono poi altre soluzioni che possono risultare vali- tica e infine daremo un’occhia-
de in casi particolari: ad esempio l’uso di file condi- ta ai piani che Microsoft ha in
visi o di messaggi di sistema come WM_COPYDA- serbo per l’infrastruttura di co-
TA. Tutti questi approcci sono ugualmente validi municazione prevista su Win-
ma hanno un problema in comune: richiedono di dows Vista.
concentrarsi sia sul modo in cui sono scambiati i
dati, sia sul loro significato, costringendoci a spen- Introduzione a Microsoft
dere tempo e risorse su questioni “secondarie”: cosa Message Queue
succede se la connessione cade? come garantire la
consegna dei messaggi? come fare per crittografa- MSMQ non è una tecnologia
re i messaggi o gestire permessi e utenti? particolarmente nuova, esiste
A queste esigenze ha risposto Microsoft con una ormai da diversi anni ed è dispo-
libreria che permette di ignorare tutti i problemi di nibile per quasi tutte le versioni
“basso livello” e di concentrarci sul lavoro che più di Windows: XP, 2000, NT4 (SP4),
ci interessa: chattare e scambiarci informazioni. 95, 98, ME. Esistono comunque
delle differenze nelle funziona-
lità supportate dai vari sistemi
Carlo Pagliei è laureato in ingegneria elettronica, lavora con operativi; per semplificare, tut-
Etere srl dal 1996 e si occupa dello sviluppo di software per to quello che diremo in seguito
il mondo del broadcast (TV, Radio). I suoi interessi principali si riferirà a Windows XP Pro-
sono l’analisi e la progettazione di sistemi e l’applicazione
pratica della programmazione object oriented. Nel tempo fessional.
libero, bimbi permettendo, si dedica alla lettura e alle nuove L’installazione è molto sem-
tecnologie. plice: basta andare nel Pannel-

36 VBJ N. 66 - Novembre/Dicembre 2005


.NET

lo di Controllo, Installazione Applicazioni, tamente con lo stesso principio: qualcuno (il


Windows Components, selezionare Message ricevente) si connette ad una coda e attende
Queuing e confermare. Appena terminato l’arrivo di messaggi, qualcun altro (il mitten-
possiamo aprire Gestione Computer, e alla te) può spedire messaggi a quella coda senza
voce Servizi e Applicazioni troveremo anche che sia fisicamente collegato ad essa.
Message Queuing: da questa console possia- I due oggetti con cui abbiamo a che fare sono
mo amministrare le varie code e dare un’oc- perciò le code ed i messaggi [1]: La coda è un
chiata alla loro organizzazione. semplice contenitore di messaggi, un messag-
La prima cosa che salta all’occhio è la pre- gio a sua volta è un contenitore di dati con
senza di tre tipi principali di code: di sistema, una serie di informazioni associate che indi-
private e pubbliche. Le code di sistema sono cano come trattarli: priorità, sicurezza, rice-
utilizzate da MSMQ per scopi che in questo vute, temporizzazioni. Chiunque può leggere
articolo non approfondiremo (ad esempio me- (o spedire) messaggi da una coda a cui ha ac-
morizzare messaggi non consegnati). Le code cesso, anche in multiutenza.
private sono accessibili solo sul PC dove ri-
siedono a patto di conoscere l’intero percor-
so d’accesso. Le code pubbliche infine sono
“replicate” su ogni PC e disponibili su tutta
MSMQ è disponibile
la rete attraverso la mediazione di Active Di- per quasi tutte
rectory, ma non sono accessibili se non si è le versioni di Windows:
parte di un dominio.
Proviamo a creare una coda ed apriamone XP, 2000, NT4,
la form delle proprietà: le varie impostazioni 95, 98, ME
riguardano quelle relative alla sicurezza,
agli utenti, ecc. Ecco il primo aspetto note-
vole della libreria: MSMQ utilizza le proce-
dure di autenticazione di Windows per ve- MSMQ prevede due tipi di utenti: dipenden-
rificare il mittente (certificati digitali, Ker- ti e indipendenti. Un utente viene definito
beros V5, NTLM), può criptare i messaggi dipendente quando ha necessità di un colle-
in modo da renderli sicuri, può registrare gamento stabile e sempre attivo con la coda,
tutte le operazioni effettuate su una certa per cui se questa non è disponibile non è in
coda. Tutto questo in maniera completamen- grado di funzionare correttamente. Gli utenti
te trasparente allo sviluppatore: non dob- indipendenti invece non necessitano di tale
biamo preoccuparci direttamente di queste collegamento e comunicano in modalità di-
funzionalità, la libreria ce le fornisce “gra- sconnessa: inviano messaggi che saranno poi
tuitamente”, inoltre funzionano nello stan- effettivamente consegnati quando la connes-
dard di Windows, perciò un qualsiasi am- sione alla rete sarà disponibile. Quest’ultima
ministratore sarà in grado di configurare il è la modalità predefinita ed è chiaramente
sistema egregiamente. quella per noi più interessante.
Accenniamo infine a due caratteristiche di
Caratteristiche principali di MSMQ MSMQ che è difficile trovare in altre librerie:
il supporto alle transazioni e i trigger.
Se vogliamo spedire un messaggio di posta Grazie al supporto alle transazioni possiamo
elettronica ci basta conoscere l’indirizzo del associare N messaggi fra loro collegati in una
destinatario, senza preoccuparci se il rice- singola transazione: MSMQ garantisce che i
vente sia effettivamente online: sarà il nostro messaggi verranno consegnati una sola vol-
motore di invio che si occuperà del lavoro di ta nell’ordine stabilito e prelevati tutti dalla
spedizione e consegna. MSMQ funziona esat- coda di destinazione, e che se anche uno solo

N. 66 - Novembre/Dicembre 2005 VBJ 37


.NET

dei passi causerà un errore, tutta la transazio- cosa, da una semplice stringa ad un ogget-
ne verrà cancellata. to serializzato.
Ultima caratteristica interessante sono i trig- Da queste poche righe si intuisce subito la
ger: è possibile specificare una serie di azio- potenza dell’accoppiata MSMQ + .NET Fra-
ni (trigger) che MSMQ esegue quando su mework: con poche righe di codice, senza
una coda si verificano determinate condizio- preoccuparci praticamente di nulla, possiamo
ni (rules). Ad esempio potremmo impostare prendere un oggetto complesso quanto si vuo-
un trigger che, quando nella coda X arriva un le, serializzarlo, impacchettarlo in un messag-
messaggio che contiene una stringa predefi- gio e spedirlo a qualcun altro senza neanche
nita, lancia un eseguibile, un file batch, uno la necessità di controllare che il destinatario
script o un oggetto COM. Con questa tecnica sia collegato. Ci basterà attendere la risposta
è ad esempio possibile realizzare dei server o una ricevuta di MSMQ che ci informerà di
che vengono lanciati semplicemente invian- eventuali problemi.
do un messaggio su una coda, senza che nes-
suna applicazione sia in esecuzione. Una semplice applicazione pratica:
MSMQ-Chat
La libreria System.Messaging
Cominciamo finalmente a scrivere qualche
Il .NET Framework, fra le sue tante librerie, riga di codice per vedere come funzionano le
ne ha una che corrisponde al namespace Sy- cose in pratica. Realizziamo una semplice appli-
stem.Messaging. Questo namespace contiene cazione dimostrativa, tipo Messenger, che serve
una serie di classi che servono a creare, ammi- a scambiare messaggi con un amico o collega:
nistrare e monitorare code, a inviare e riceve- abbiamo una finestra che visualizza gli utenti
re messaggi: l’attuale implementazione della registrati (code), ne scegliamo uno, ci colleghia-
libreria si appoggia proprio su MSMQ [2]. mo con l’utente, e iniziamo a chattare.
Problema 1: come fare per avere la lista degli
utenti? Ipotizziamo che ad ogni utente corri-
sponda una diversa coda ed utilizziamo il me-
MSMQ supporta todo statico MessageQueue.GetPublicQueues()
funzionalità avanzate che ci fornisce la lista delle code pubbliche
registrate. Se non siamo in un dominio pos-
come la gestione siamo usare GetPrivateQueuesByMachine()
degli utenti, le transazioni per ottenere le code private di un particolare
e i trigger PC. Ottenuta la lista riempiamo un TreeView
per visualizzarla.
Problema 2: come gestire lo scambio di mes-
saggi? Utilizziamo due classi: IpcQueue e Ipc-
La classe più importante è MessageQueue, Message. IpcQueue farà per noi il lavoro del
che espone metodi per inviare e ricevere in postino trasmettendo un oggetto IpcMessage
modalità sia sincrona che asincrona, control- che, oltre al messaggio vero e proprio, conter-
lare la presenza di messaggi, ricercare code rà l’indirizzo del mittente e altre informazio-
secondo vari criteri. ni supplementari.
L’altra classe fondamentale è Message, che Per quanto riguarda la classe IpcQueue ab-
contiene il messaggio vero e proprio insieme a biamo bisogno di poche cose: due metodi per
svariati parametri di controllo: Timeout, Ack- avviare e chiudere la connessione con la coda,
nowledgements, Authentication. I dati da in- StartListening() e StopListening(), un meto-
viare vengono inseriti nella proprietà Body: do che ci consente di inviare un messaggio
al suo interno può essere inserita qualsiasi ad una coda qualsiasi, SendTo(), e un even-

38 VBJ N. 66 - Novembre/Dicembre 2005


.NET

to che ci avverte dell’arrivo di un messaggio. private IAsyncResult _listening;


Internamente la classe utilizza due oggetti ...
MessageQueue, uno per la ricezione ed uno
per l’invio. Nel costruttore IpcQueue() su en- private void _receiveCompleted(object sender,
trambe le code va inizializzato il formatter che System.Messaging.ReceiveCompletedEventArgs e) {
codificherà il messaggio, specificando esplici- try {
tamente la classe IpcMessage da serializzare. Message m = _rxQueue.EndReceive(e.AsyncResult);
Sulla classe “ricevente” va anche impostato IpcMessage msg = new IpcMessage();
l’evento che informerà dell’arrivo di un nuovo msg = (IpcMessage)m.Body;
messaggio. Il frammento di codice che segue /* codice che gestisce l’evento */
descrive le operazioni da effettuare: ...
}
_rxQueue = new MessageQueue(); finally {
Type[] typArray = new Type[]{typeof(IpcMessage)}; _listening = _rxQueue.BeginReceive();
_rxQueue.Formatter = new XmlMessageFormatter }
(typArray); return;
_rxQueue.ReceiveCompleted += }
new ReceiveCompletedEventHandler
(this._receiveCompleted); Non c’è molto da commentare: il codice è
semplice e abbastanza intuitivo anche se non
Vediamo ora brevemente come fare per in- si ha una approfondita conoscenza di System.
viare un messaggio: basta creare l’oggetto Messaging. Quello che si nota è l’estrema sem-
IpcMessage, inizializzarlo e passarlo al me- plicità e pulizia del codice che nasconde quasi
todo Send() che internamente ed in maniera tutti i dettagli; l’unica scelta da fare è quella
trasparente provvederà a formattarlo come del serializzatore, che naturalmente deve esse-
XML e inviarlo al destinatario: re lo stesso per il mittente ed il destinatario.
L’applicazione completa è disponibile sul sito
public void SendTo(string address, Ftp di Infomedia, inoltre su [3] potete trovare
string aSubject, una trattazione di MSMQ e System.Messaging
string aMessage){ discretamente approfondita e con svariate ap-
IpcMessage msg = new IpcMessage(); plicazioni di esempio.
msg.SenderPath = _rxQueue.PathName;
msg.Subject = aSubject; Il futuro: Windows Communication
msg.Body = aMessage; Foundation
_txQueue.Path = address;
_txQueue.Send(msg); Chi decide di appoggiarsi al .NET Framework
} per scrivere applicazioni lo fa per diversi mo-
tivi, uno dei quali è sicuramente il fatto che
Resta infine da vedere come implementare Microsoft sta spingendo su di esso in maniera
la ricezione; utilizziamo quella asincrona, al- molto forte. Il prossimo anno dovrebbe essere
trimenti l’applicazione sarebbe bloccata fino molto importante dal punto di vista dello svi-
alla ricezione di un messaggio. Il codice è luppatore, a fine 2006 è previsto infatti il rila-
molto semplice; appena arriva un messag- scio della prima versione ufficiale di Windows
gio viene attivato l’evento _receiveComple- Vista: il sistema operativo, ora allo stadio di
ted(), che internamente provvede a deseria- beta 1, che prenderà il posto di XP.
lizzare il messaggio, ad eseguire su di esso Insieme a Windows Vista verrà rilasciato an-
le operazioni richieste ed infine a riavviare che WinFX: una serie di librerie di alto livel-
la ricezione: lo (Foundations), basate sul .NET framework,

N. 66 - Novembre/Dicembre 2005 VBJ 39


.NET

che costituiranno il nuovo modello di pro- ne beta 1 che i vari SDK di tutte le Founda-
grammazione Windows. L’SDK ed il runtime tion anche per Windows XP.
di WinFX saranno disponibili, sempre a fine
2006, anche per Windows XP e Windows Ser- Conclusioni
ver 2003.
In questo scenario di cambiamenti un po- Abbiamo mostrato come sia possibile scri-
sto in prima fila se l’è guadagnato Windows vere applicazioni che comunicano in maniera
Communication Foundation (nome in codice semplice ed affidabile appoggiandosi a MSMQ
Indigo): la nuova infrastruttura di comunica- utilizzando, in maniera trasparente e senza il
zione di Windows. Si tratta di un insieme di diretto intervento dello sviluppatore, sia tutte
tecnologie, costruite attorno ai Web Service, le caratteristiche di sicurezza che offre Win-
che sono la naturale evoluzione delle tecno- dows (gestione degli utenti, crittografia, au-
logie attualmente disponibili: COM, COM+, tenticazioni, ecc.) sia caratteristiche avanzate
MSMQ, ASMX, ecc. Tutte le funzionalità di quali il supporto alle transazioni, che sareb-
Indigo sono basate sul .NET Framework, bero di difficile implementazione utilizzando
esposte come managed API e sono esten- ad esempio una socket TCP.
sioni delle attuali librerie di Remoting, Web Abbiamo anche scoperto che utilizzando
Service, Messaging ed Enterprise Services. MSMQ attraverso la libreria System.Messa-
Su [6] si può leggere un buon articolo che ging del .NET Framework siamo in grado
introduce le idee alla base di Indigo, spiega di supportare sia sistemi legacy basati sul-
i nuovi concetti di servizi e contratti e infi- le API MSMQ, sia i futuri sistemi basati su
ne descrive la libreria System.ServiceModel. Indigo.
Attraverso l’uso di codice dimostrativo scen-
de nel dettaglio abbastanza da capire come Bibliografia
viene progettata e costruita una nuova appli-
cazione e come interagisce col mondo che la [1] MSDN - “Message Queuing (MSMQ)”,
circonda. Attualmente WinFX è in versione http://msdn.microsoft.com/library/default.
beta 1, quindi potrebbero ancora esserci dei asp?url=/library/en-us/msmq/msmq_over-
cambiamenti di un certo rilievo, ma comun- view_4ilh.asp
que chi scrive oggi dovrebbe essere in grado [2] MSDN – “System.Messaging namespace”,
di utilizzare quelle nuove cambiando poco o http://msdn.microsoft.com/library/default.
nulla. Siamo pian piano arrivati alla parte in- asp?url=/library/en-us/cpref/html/frlrfsy-
teressante che dovrebbe far ingolosire qual- stemmessaging.asp
siasi sviluppatore: Microsoft afferma infatti [3] Adrian Turtschi et al. – “C# Book, Cap. 7:
che tutti i sistemi basati su Indigo saranno in Message Queuing using MSMQ”, Syngress,
grado di comunicare con sistemi che suppor- 2002
tano MSMQ e viceversa [5], perciò chi oggi [4] Microsoft – “Windows Vista Developer Cen-
sceglie di appoggiarsi alla libreria System. ter”, http://msdn.microsoft.com/windowsvi-
Messaging si trova nella condizione ideale sta/
di poter scrivere codice multipiattaforma in [5] Microsoft - “Indigo Frequently Asked Que-
grado di supportare sia sistemi legacy basa- stions”, http://msdn.microsoft.com/win-
ti sulle API MSMQ (COM), sia sistemi futu- dowsvista/support/faq/communication/
ri basati su Indigo. Chi fosse interessato ad [6] Clemens Vasters – “Introduction to Buil-
approfondire l’argomento, sul Windows Vista ding Windows Communication Foundation
Developer Center [4] può trovare informazio- Services”, http://msdn.microsoft.com/web-
ni preliminari, FAQ, approfondimenti, libri, services/indigo/default.aspx?pull=/library/
white paper, blog e quant’altro. Si possono en-us/dnlong/html/introtowcf.asp#introt_
infine scaricare sia Windows Vista in versio- topic1

40 VBJ N. 66 - Novembre/Dicembre 2005


.NET

La GAC in salsa XML


Convertiamo la GAC in un file XML per recuperare velocemente le
informazioni su assembly, versioni e namespace

di Filippo Bonanni GAC

N
ell’articolo sul motore di scripting in .NET so nome dell’assembly e quindi
presente nel numero 64 abbiamo lasciato un’ulteriore directory dal nome
in sospeso la questione di referenziare as- di tipo Version__PublicKeyToken
sembly di terze parti registrati nella GAC. Più in per ogni versione registrata.
generale possiamo porci questa domanda: esiste Ad esempio il percorso dell’as-
un modo per scoprire, partendo da un namespace, sembly System.Data.dll, potreb-
l’assembly in cui è contenuto? be apparire così
La risposta che mi era venuta in mente consiste-
va nell’utilizzare la Reflection (vedi [1]) per ispe- Directory di C:\WINDOWS\assembly\
zionare gli assembly alla ricerca del namespace in GAC\System.Data
questione, ma questa non è certo un’operazione
comoda da eseguire frequentemente; se però “sin- 17/03/2005 11.35 <DIR> .
cronizziamo” la GAC con un file, magari XML, nel 17/03/2005 11.35 <DIR> ..
quale esportare l’elenco degli assembly con le in- 17/03/2005 11.35 <DIR>
formazioni sulle versioni e sui namespace in essi 1.0.5000.0__b77a5c561934e089
contenuti, diventa tutto più accessibile. 0 File 0 byte
In questo articolo vedremo come realizzare un 3 Directory 17.287.491.584
“GACInspector”, un componente che possa essere byte disponibili
utilizzato per questo scopo: generare un file XML
riproduzione fedele della GAC. Il file è contenuto nella cartel-
la 1.0.5000.0__b77a5c561934e089
La GAC in breve e se ci fossero state più versioni
avremmo trovato altre cartelle
La Global Assembly Cache non è altro che una di- analoghe a questa. In ogni car-
rectory, chiamata GAC, di solito contenuta nel per- tella è presente anche un file
corso %windir%\assembly. __AssemblyInfo__.ini riportan-
Per ogni assembly registrato, viene creata una te un riepilogo delle informa-
directory sotto tale percorso chiamata con lo stes- zioni sull’assembly:

[AssemblyInfo]
Signature=a3ba424f0b663038e86ae83
Filippo Bonanni si occupa di informatica dal 1998 ed al f72ffe2a5c2722466
momento i suoi interessi sono rivolti principalmente all’am- MVID=c5596d3e16daa840b86afe4a5bf
biente .NET. Attualmente lavora nel team di sviluppo della
c9e06
D&T Informatica di Sesto Fiorentino in progetti web-based
di interfacciamento a sistemi AS/400 e di archiviazione URL=file:///C:/WINDOWS/Microsoft.NET/
ottica in ASP.NET. Framework/v1.1.4322/System.Data.dll

42 VBJ N. 66 - Novembre/Dicembre 2005


.NET

DisplayName=System.Data, Version=1.0.5000.0, name=“calcr.dll”


Culture=neutral, PublicKeyToken=b77a5c561934e089 >
<ver
Signature è la firma digitale ottenuta da una id=“5.0.0.0__a1690a5ea44bab32”
combinazione dell’hash del file e della chiave DisplayName=“CalcR”
privata (facente parte della coppia Private/Public Version=“5.0.0.0”
Key utilizzate per l’assegnazione dello Strong Culture=“neutral”
Name), MVID (Module Version ID) è un GUID PublicKeyToken=“a1690a5ea44bab32”
generato durante la compilazione, URL indica la >
posizione dell’assembly ed infine DisplayName <namespaces>
fornisce informazioni sullo Strong Name. <name>Samples.Math.Calculator</name>
Ecco la rappresentazione dello stesso assem- </namespaces>
bly nel file XML: </ver>
<ver
<assembly id=“6.0.0.0__a1690a5ea44bab32”
folder=“system.data” DisplayName=“CalcR”
name=“System.Data.dll” Version=“6.0.0.0”
> Culture=“neutral”
<ver PublicKeyToken=“a1690a5ea44bab32”
id=“1.0.5000.0__b77a5c561934e089” >
DisplayName=“System.Data” <namespaces>
Version=“1.0.5000.0” <name>Samples.Math.Calculator</name>
Culture=“neutral” </namespaces>
PublicKeyToken=“b77a5c561934e089” </ver>
> </assembly>
<namespaces>
<name>System</name> Con una struttura del genere, per risalire dal
<name>System.ComponentModel</name> namespace all’assembly che lo contiene è suf-
<name>System.Data</name> ficiente una semplice query XPath (vedi [2])
<name>System.Data.Common</name> che restituirà uno o più nodi, a seconda che
<name>System.Data.Odbc</name> esistano una o più versioni o che il namespa-
<name>System.Data.OleDb</name> ce sia ripetuto in più assembly.
<name>System.Data.SqlClient</name>
<name>System.Data.SqlTypes</name> L’algoritmo di sincronizzazione
<name>System.Xml</name>
</namespaces> In Figura 1 è riportato il flusso decisionale
</ver> del nostro componente: se l’assembly (nel-
</assembly> la figura “Asm”), non è più in GAC viene ri-
mosso dal file XML, se invece c’è e non è an-
Come si può vedere, la struttura replica le cora stato censito viene aggiunto; lo stesso
informazioni contenute nella GAC ed in più procedimento è eseguito per le versioni, ag-
offre un elenco di tutti i namespace presen- giungendo le nuove e rimuovendo quelle non
ti nel file. Se invece il file ispezionato avesse più presenti. A questo punto, per ogni nuo-
avuto più versioni, il risultato sarebbe stato va versione trovata si procede con l’ispezio-
come il seguente esempio: ne dell’assembly relativo, alla ricerca di tut-
ti i namespace in esso contenuti che vengo-
<assembly no successivamente aggiunti nel documen-
folder=“calcr” to XML.

N. 66 - Novembre/Dicembre 2005 VBJ 43


.NET

Struttura del programma VerifyAssembly()


end set
Prima di iniziare l’ispezione dell’assembly end Property
occorre fornire al programma alcune infor-
mazioni basilari: il percorso della GAC (che Public Sub New(GACPath as String, OutputFile
non dimentichiamoci può essere modifica- as String)
to), il percorso completo del file XML di out- If GACPath Is Nothing Then GACPath=String.
put ed infine il nome dell’assembly da ana- Empty
lizzare If OutputFile Is Nothing Then OutputFile=
String.Empty
public Property AssemblyName as String _GACPath=GACPath.Trim()
get If _GACPath=String.Empty Then Throw New Exception
Return _AssemblyName (“Specifica il percorso della GAC”)
end get If Not(_GACPath.EndsWith(“\”)) Then _GACPath+=“\”
set
_AssemblyName=Value.Trim() _filename=OutputFile.Trim()
If _AssemblyName=String.Empty Then If _filename=String.Empty Then Throw New Exception
__AssemblyName=Nothing (“Specifica un nome di file di output valido”)
assemblyFolder=_AssemblyName.Substring(0,
__AssemblyName.LastIndexOf(“.”)) Me.LoadXml()
assemblyFolder=assemblyFolder.toLower() End Sub
completeAssemblyPath=_GACPath & assemblyFolder
If Not(completeAssemblyPath.EndsWith(“\”)) Il percorso della GAC e il file di output
Then completeAssemblyPath+=“\” sono dichiarati come parametri da passare
al costruttore poiché rimarranno invariati
durante il ciclo di vita del componente men-
tre il nome dell’assembly è una proprietà
che potrà essere aggiornata per passare al-
l’elemento successivo registrato in GAC.
Nel costruttore richiamiamo il metodo Loa-
dXml() che crea il file XML nel caso non esi-
sta ancora e lo carica in un XmlDocument
(vedi [1]); nella proprietà AssemblyName re-
cuperiamo il nome della cartella contenen-
te l’assembly (che come abbiamo detto è il
nome del file stesso senza il suffisso .dll o
.exe) e, con il metodo VerifyAssembly(), veri-
fichiamo la sua esistenza nella GAC. Da nota-
re che partendo dall’analisi della GAC, quel-
lo che avremo immediatamente a disposizio-
ne sarà il nome della directory e non quel-
lo del file, quindi dotiamo il componente di
un ulteriore metodo che permetta di fare il
percorso inverso:

Public Function GetAssemblyName(assemblyFolder


Figura 1 Il flusso del GACInspector as String) as String
Dim Result as String

44 VBJ N. 66 - Novembre/Dicembre 2005


.NET

assemblyFolder=_GACPath & assemblyFolder ziamo un oggetto XmlNode per la creazione


Result=Directory.GetFiles(Directory.GetDirectories del nodo e un oggetto XmlAttribute per l’in-
(assemblyFolder)(0))(0) serimento degli attributi:
Result=Result.SubString(Result.LastIndexOf
(“\”)+1) If findNode Is Nothing Then
Return Result newNode=doc.CreateNode(XmlNodeType.Element,
End Function “assembly”, ““)

Da una cartella di tipo %GACPATH%\as- attrib=doc.CreateNode(XmlNodeType.Attribute,


semblyFolder recuperiamo dalla prima sot- “folder”,”“)
todirectory (una delle tante possibili ver- attrib.value=assemblyFolder
sioni dell’assembly) il primo file (poiché i newNode.Attributes.Append(attrib)
file saranno solo due e __AssemblyInfo__
.ini sarà sempre al secondo posto per via attrib=doc.CreateNode(XmlNodeType.Attribute,
del suo nome, il primo sarà sempre quello “name”,”“)
voluto) per ottenere il nome da utilizzare attrib.value=_AssemblyName
nella proprietà. newNode.Attributes.Append(attrib)

Rimozione di assembly non più in GAC doc.DocumentElement.AppendChild(newNode)


doc.save(_filename)
Se la verifica dell’esistenza dell’assembly in End If
GAC ha dato esito negativo può essere dovu-
to al fatto che tutte le versioni sono state ri- Ricerca di nuove versioni
mosse e quindi occorre rimuovere tutte le re-
ferenze anche dal file XML: Scendiamo di un livello ed incominciamo ora
l’analisi delle versioni dell’assembly. Per veri-
Private Sub RemoveAssembly() ficare la presenza di nuove versioni memoriz-
Dim findNode as XmlNode=doc.SelectSingleNode(“/GAC/ ziamo in un Array di stringhe tutte le possibili
assembly[@folder=’“ & assemblyFolder & “‘]”) directory di versione (quelle di tipo Version_
If Not(findNode Is Nothing) Then _PublicKeyToken) presenti in GAC mediante
doc.DocumentElement.RemoveChild(findNode) il metodo Directory.GetDirectories():
doc.save(_filename)
End If Private Function GetAssemblyVersions(AbsolutePath
End Sub as boolean) as String()
Dim Result() as String
Con una query XPath proviamo a recupera- Dim i as integer
re il nodo <GAC><assembly> con attributo Result=Directory.GetDirectories(complete
folder uguale alla directory non più presente AssemblyPath)
in GAC e se lo troviamo procediamo alla sua If Not(AbsolutePath) Then
eliminazione. For i=0 to Result.Length-1
Result(i)=Result(i).Replace(completeAssembly
Aggiunta di nuovi assembly Path,”“)
Next
L’aggiunta prevede, come per la rimozione, End If
una ricerca dell’assembly all’interno del file Return Result
XML; stavolta però, se l’elemento non viene End Function
trovato, si procede alla creazione del nodo con
l’assegnazione degli attributi; per farlo utiliz- La variabile booleana AbsolutePath permet-

N. 66 - Novembre/Dicembre 2005 VBJ 45


.NET

te di decidere se memorizzare il percorso as- Next


soluto o relativo all’interno dell’Array. doc.save(_filename)
Fatto ciò, confrontiamo le versioni presenti in End Sub
GAC con quelle del file XML sempre tramite
una query XPath, stavolta però a partire dal Le versioni presenti nel file XML sono me-
nodo <assembly> (passato come parametro a morizzate in un XmlNodeList estraendo tutti
valore nella variabile Node), memorizzando in i nodi-figlio <ver> dall’elemento <assembly>
un’ArrayList tutte quelle nuove: fornito come parametro alla funzione.

Private Sub FindNewVersion(ByRef alVer as Array Aggiunta di nuove versioni


List, ByVal Node as XmlNode)
Dim arrTemp() as String Le nuove versioni sono tutte quelle presen-
Dim i as Integer ti nell’ArrayList generata dal metodo Find-
Dim findNode as XmlNode NewVersion(), quindi per ogni suo elemento
arrTemp=GetAssemblyVersions(True) dobbiamo creare un nodo <ver> con i relati-
vi attributi id, DisplayName, Version, Cultu-
For i=0 to arrTemp.Length-1 re e PublicKeyToken.
findNode=Node.SelectSingleNode(“ver[@id=’“ &
arrTemp(i).SubString(arrTemp(i).LastIndexOf
(“\”)+1) & “‘]”) Esiste un modo per
If findNode Is Nothing Then alVer.Add
(arrTemp(i))
scoprire, partendo da
Next un namespace, l’assembly
End Sub
in cui è contenuto
Eliminazione di Versioni

Con un confronto inverso – tramite il metodo Mentre il primo è esattamente il nome del-
Array.IndexOf() che consente di ricercare un la cartella di versione, gli altri attributi devo-
oggetto all’interno di una matrice di oggetti, no essere recuperati dal file __AssemblyInfo__
cioè partendo dalle versioni presenti nel file .ini che leggiamo attraverso uno StreamRea-
XML e verificandone l’esistenza nella GAC, der (vedi [1]) recuperando il rigo che inizia
eliminiamo tutti i nodi non più necessari: per “DisplayName” e dividendolo successi-
vamente in una matrice:
Private Sub ClearRemovedVersion(ByVal Node as
XmlNode) Private Sub AddNewVersion(alVer as ArrayList,
Dim arrTemp() as String Node as XmlNode)
Dim i as Integer [Dichiarazione delle variabili]
Dim verNodeList as XmlNodeList For i=0 to alVer.Count-1
Esci=False
arrTemp=GetAssemblyVersions(False)
sr=New StreamReader(alVer(i).ToString & “\”
verNodeList=Node.SelectNodes(“ver”) & iniFile)
Do
For i=0 to verNodeList.Count-1 tempString=sr.ReadLine
If Array.IndexOf(arrTemp,verNodeList.Item(i). If tempString.StartsWith(“DisplayName”)
Attributes.ItemOf(“id”).Value)=-1 Then Then Esci=True
Node.RemoveChild(verNodeList.Item(i)) Loop Until Esci or sr.Peek=-1

46 VBJ N. 66 - Novembre/Dicembre 2005


.NET

sr.Close() Una volta recuperati tutti i namespace li


arrTemp=tempString.Split(“,”) aggiungiamo sotto l’elemento <ver> com-
[Creazione del nodo <ver>] pletando l’estrazione delle informazioni sul-
For j=0 to arrTemp.Length-1 l’assembly.
[Creazione degli attributi]
Next Conclusioni
[Chiamata alla funzione che recupera i
namespace] Affinché il file XML possa essere di una qual-
[Aggiunta del nodo <ver> sotto il nodo che utilità, occorre che sia sempre allineato
<assembly>] con la GAC, quindi è necessario utilizzare il
Next componente descritto all’interno di un pro-
doc.save(_filename) gramma che la monitorizzi costantemente.
End Sub Nel codice allegato a questo articolo è dispo-
nibile un file d’esempio “GACWatcher.vbns”
Ispezione dell’assembly in cerca dei (eseguibile con il motore di scripting per
namespace .NET descritto nel numero precedente) che
tramite un oggetto FileSystemWatcher (vedi
A questo punto ci resta soltanto da ispezio- [1]) controlla costantemente la GAC passan-
nare l’assembly alla ricerca dei namespace do al GACInspector il nome della cartella mo-
in esso contenuti e per farlo ricorriamo alla dificata da ispezionare mediante due metodi,
indispensabile Reflection. Dopo aver caricato OnChanged() e OnDeleted(), aggiunti proprio
il file mediante la classe Assembly (vedi [1]) per questo scopo; la soluzione più idonea sa-
basta semplicemente estrarre in una matrice rebbe quella di utilizzare questo codice per la
tutti i tipi contenuti in esso e scorrerli alla ri- realizzazione di un servizio che parta all’ac-
cerca dei namespace: censione del computer e resti quindi sempre
attivo in background.
Dim a as [Assembly] Il file d’esempio “BuildGACFile.vbns” inve-
Dim arrT() as Type ce, permette di creare il file XML con la situa-
Dim alNamespace as New ArrayList() zione attuale della GAC.
a=[Assembly].LoadFile(verPath & _AssemblyName) Per utilizzare il file XML all’interno del “mo-
arrT=a.GetTypes tore di scripting per .NET” è sufficiente ag-
For i=0 to arrT.Length – 1 giungere una funzione che, partendo dal nome
If Not(arrT(i).NameSpace Is Nothing) And dell’assembly, con una query XPath recuperi
(alNamespace.IndexOf(arrT(i).NameSpace)=-1) il nodo contenente l’assembly stesso e quin-
Then alNamespace.Add(arrT(i).NameSpace) di ricostruisca il percorso completo da utiliz-
Next zare per referenziare il file al momento della
compilazione. Il nome dell’assembly potreb-
Il metodo Assembly.GetTypes() ci permette be essere fornito come elemento del tag <re-
di recuperare tutti i tipi e utilizzando nel ciclo ferences> con intestazione <gac> per distin-
il confronto con la proprietà Type.Namespa- guerlo da quelli <prv>.
ce, che restituisce il namespace del Tipo, in-
dividuiamo le informazioni volute. Da notare Riferimenti
che in un assembly ci possono tranquillamen-
te essere molti Tipi appartenenti allo stesso [1] .NET Framework SDK – http://msdn.mi-
namespace, quindi per evitare di recuperare crosoft.com/netframework/support/docu-
il medesimo nome più volte verifichiamo con mentation
il metodo ArrayList.IndexOf che l’elemento [2] XPath Tutorial – http://www.w3schools.
non sia già presente nell’ArrayList. com/XPath

N. 66 - Novembre/Dicembre 2005 VBJ 47


SOFTWARE ENGINEERING

Model Driven
Architecture
Model Driven Architecture (MDA) è il termine con cui OMG identifica il suo tenta-
tivo di creare una architettura per lo sviluppo di applicazioni indipendenti dalla
piattaforma

di Lorenzo Vandoni

C
on il nome di Model Driven Architecture OMG e MDA
(MDA) viene indicato quello che, ultima-
mente, è diventato uno degli argomenti mag- OMG è un’organizzazione che
giormente dibattuti tra i progettisti legati ai meto- si occupa principalmente di
di object-oriented. standard nel mondo dell’ana-
La proposta arriva dall’Object Management Group lisi, della progettazione e della
(OMG), e l’idea è quella di separare completamente programmazione object-orien-
la logica applicativa dalla piattaforma sulla quale ted (OOA, OOD, OOP). Uno de-
l’applicazione dovrà essere implementata. gli scopi di OMG è quello di
Il modello dell’applicazione viene sviluppato uti- creare meccanismi che permet-
lizzando linguaggi di alto livello come UML, CWM tano di applicare le medesime
(Common Warehouse Metamodel) e MOF (Meta- tecniche di sviluppo, indipen-
Object Facility), e viene quindi mappato su diver- dentemente dal linguaggio di
se piattaforme, come CORBA, COM, Java o .NET. programmazione e dal sistema
Il beneficio di MDA è costituito dal fatto che il mo- operativo utilizzato.
dello applicativo rimane costante e può essere uti- Questi sforzi hanno portato,
lizzato anche per sfruttare le successive evoluzio- negli anni ’90, alla definizione
ni della tecnologia sottostante, o nuove piattafor- di CORBA, uno standard per
me applicative non ancora esistenti nel momento l’implementazione e l’utilizzo di
in cui il programma è stato sviluppato. oggetti distribuiti, multilinguag-
La conversione dal modello generico, indipenden- gio e multipiattaforma. CORBA
te dalla piattaforma, ad un modello più specifico, ha avuto un buon successo, so-
legato a una particolare tecnologia, viene aiutata da prattutto in ambiente Unix, ed
linee guida specifiche, e può essere automatizzata è tuttora molto utilizzato, anche
almeno parzialmente da strumenti CASE. se l’attenzione degli sviluppato-
ri, soprattutto in ambiente Win-
dows, è stata principalmente ri-
Lorenzo Vandoni è laureato in Informatica, ed è uno specialista volta su meccanismi alternativi,
di progettazione e sviluppo con tecniche e linguaggi object- come COM, DCOM e, ultima-
oriented. Attualmente è direttore del Laboratorio di Ricerca e mente, i Web Service.
Sviluppo di Emisfera e coordina un progetto di ricerca sulle
Reti Wireless finanziato nell’ambito del Sesto Programma Con MDA, OMG cerca di anda-
Quadro (FP6) della Comunità Europea. Può essere contattato re un passo al di là di CORBA,
tramite e-mail all’indirizzo vandoni@infomedia.it suggerendo un metodo di lavoro

48 VBJ N. 66 - Novembre/Dicembre 2005


SOFTWARE ENGINEERING

che si renda indipendentente da


qualunque dettaglio implemen-
tativo. Applicando MDA, diviene
teoricamente possibile definire
il comportamento dell’applica-
zione in modo del tutto astrat-
to, delegando poi la conversione
degli schemi in codice a mecca-
nismi di traduzione più o meno
automatizzati.

L’architettura di MDA

Nella definizione di MDA,


OMG ha cercato di considerare
in modo pragmatico lo stato del-
l’arte nell’ambito di OOA, OOD
e OOP. Per quanto riguarda ana-
lisi e progettazione, ovviamente,
il linguaggio di riferimento è or-
mai da anni UML.
A questo linguaggio, però, Figura 1 L’architettura di MDA
OMG ha affiancato i meno noti
CWM (Common Warehouse Me-
tamodel), un linguaggio per la
modellazione di database e data warehouse, creare un modello UML dell’applicazione, in-
MOF (Meta Object Facility), per la gestione dipendente da ogni specifica piattaforma di
degli oggetti all’interno di repository, e XMI implementazione, basandolo su un determi-
(XML Metadata Interface), come formato di nato core model. Un core model, o UML profi-
scambio dei modelli. le, è una specie di meta-modello, che descri-
In pratica, questo significa che i modelli po- ve le principali caratteristiche comuni ad una
tranno essere costruiti con UML, scambiati determinata classe di applicazioni, come ad
con XMI, e memorizzati in repository MOF. esempio i programmi gestionali.
Come si può vedere dalla Figura 1, UML,
MOF e CWM sono gli elementi centrali del-
l’architettura di MDA, e consentono di ma-
scherare le differenze fra i vari “middleware”
L’ultimo passo
indicati nell’anello più esterno, e cioè Java, è costituito
.NET, Web Service e CORBA. Tutti questi si- dalla generazione
stemi, anche se in modi diversi, forniscono un
insieme di servizi che vengono utilizzati dalle del codice applicativo
applicazioni, tra cui funzionalità di sicurezza,
transazioni e servizi di directory.
In teoria, questo compito sarà riservato agli
Lavorare con MDA analisti “puri”, mentre il passo successivo,
costituito dalla conversione del modello ge-
Costruire un’applicazione conforme all’ar- nerico in un modello specializzato che fac-
chitettura di MDA significa, come prima cosa, cia riferimento ad una specifica piattaforma

N. 66 - Novembre/Dicembre 2005 VBJ 49


SOFTWARE ENGINEERING

di implementazione, come Java o .NET, sarà re una profonda conoscenza di alcuni domi-
ad appannaggio di personale che conosca i ni applicativi, che con MDA è stata messa in
dettagli della piattaforma prescelta. Questo pratica creando dei modelli UML che tradu-
passaggio sarà però guidato da alcune regole cono questa conoscenza in qualcosa di più fa-
di conversione, e quindi potrà essere alme- cilmente condivisibile.
no in parte automatizzato da parte di stru- Per ognuno di questi domini applicativi è
menti CASE. stato creato un modello UML astratto, indi-
Questo primo processo di conversione potrà pendente dalla piattaforma, ed un modello
produrre, oltre ad un modello UML specializ- UML specifico, che serva anche come esem-
zato, anche del codice o altri elementi che po- pio di traduzione.
tranno servire direttamente all’implementa-
zione, come ad esempio dichiarazioni di inter- Sfruttare i servizi delle piattaforme
facce o schemi di tabelle relazionali.
Il modello UML specializzato potrà con- Ognuna delle piattaforme target conside-
tenere elementi “dialettali” specifici della rate per l’implementazione offre una serie
piattaforma di implementazione prescel- di servizi, tra cui quelli più comuni sono la
ta, per meglio identificare come un deter- gestione delle transazioni, della persistenza
minato aspetto dell’applicazione dovrà es- e della sicurezza. Ognuno di questi servizi
sere implementato con gli strumenti mes- viene definito in MDA in modo indipenden-
si a disposizione. Avremo quindi, a secon- te dalla piattaforma, in modo che possa es-
da dei casi, elementi che rappresenteranno sere referenziato nel modello generico del-
un Web Service, un componente EJB, o una l’applicazione.
stored procedure.
L’ultimo passo è costituito dalla generazio-
ne del codice applicativo a partire dal model-
lo specializzato. Questo processo viene faci- L’idea è quella di
litato dalla disponibilità degli elementi “dia-
lettali” appena citati, che potranno essere fa-
separare completamente
cilmente messi in corrispondenza con parti la logica applicativa
di codice. dalla piattaforma sulla
L’obiettivo di quest’ultima conversione è
quello di ottenere in modo automatico una quale l’applicazione dovrà
percentuale significativa del codice applica- essere implementata
tivo effettivamente richiesto, in modo da ri-
durre il lavoro da effettuare, la probabilità
di commettere errori, e quindi il costo del-
lo sviluppo. In questo modello, cioè, si potrà specifica-
re di volere utilizzare in modo generico una
Modellare i domini transazione. Saranno poi le regole di map-
ping specifiche per ogni piattaforma che tra-
L’idea di creare dei meta-modelli di un parti- durranno questa generica richiesta in un mo-
colare dominio applicativo non è nuova, ed in dello più specifico, che sfrutterà l’implemen-
OMG era stata finora tradotta in pratica trami- tazione del servizio disponibile sulla piatta-
te la definizione di interfacce IDL che permet- forma prescelta.
tessero di creare servizi CORBA standardizza- Anche le applicazioni già sviluppate con tec-
ti per ogni specifico settore applicativo. nologie precedenti (il cosiddetto codice “le-
Questa esperienza, che non ha avuto una gacy”) possono essere incorporate in MDA tra-
grande risonanza, è servita però a genera- mite uno strato di codice esterno, in modo da

50 VBJ N. 66 - Novembre/Dicembre 2005


SOFTWARE ENGINEERING

permettere, da una parte, di integrarle con le Non si può negare che questo sia un pro-
nuove applicazioni sviluppate e, dall’altra, di blema reale. Molti di noi hanno vissuto nella
migliorare il vecchio codice sfruttando i ser- propria carriera transizioni più o meno trau-
vizi resi disponibili dalle nuove piattaforme matiche da Dos a Windows, da 16 a 32 bit, da
e modellati con MDA. VB6 a .NET, per non parlare dei “veri” por-
ting tra linguaggi e sistemi operativi diversi.
Potenziali benefici di MDA A molti, più volte, è capitato di dover riscri-
vere la stessa applicazione.
I potenziali benefici che questo approccio
porta con sé sono molti, e principalmente le-
gati alla netta separazione che viene impo-
sta tra logica applicativa e tecniche di imple- Il modello
mentazione.
Anzitutto, MDA risulta essere un’architet- dell’applicazione viene
tura del tutto aperta ed estendibile, anche in sviluppato
vista di possibili future evoluzioni tecnologi-
che. Ogni nuovo linguaggio, sistema opera-
utilizzando linguaggi
tivo o piattaforma, è infatti potenzialmente di alto livello
incapsulabile in questa architettura, che pro- come UML
mette il porting delle applicazioni tra piatta-
forme diverse, con uno sforzo di implemen-
tazione minimo.
Ci saranno poi benefici a livello di normaliz- Forse MDA non sarà la soluzione definitiva
zazione e standardizzazione del codice, che fa- per questi problemi, però il fatto di essere ba-
voriranno la possibilità da parte di più persone sata su standard e, soprattutto, la maggiore
di intervenire sulla stessa applicazione. sensibilità emersa negli ultimi anni relativa-
La stesura dei core models, inoltre, potrà fa- mente alla necessità di aderire ad essi, dan-
vorire una migliore comprensione di vari do- no a questo approccio concrete possibilità di
mini applicativi, trasformando conoscenze più realizzazione.
o meno vaghe in modelli condivisibili. Va anche notato, d’altra parte, che MDA va
quasi in direzione opposta rispetto ad altri
Conclusioni movimenti emergenti, quelli delle metodolo-
gie agili. Da una parte abbiamo un’attenzione
L’idea alla base di MDA è sicuramente inte- quasi ossessiva per le fasi di analisi, dall’al-
ressante, anche se non originalissima. Molti tra un atteggiamento più pragmatico, e una
sono stati infatti i tentativi di portare la defini- maggiore attenzione per gli aspetti umanistici
zione delle applicazioni ad un livello di astra- del proprio lavoro, con particolare enfasi per
zione più alto, in modo da svincolarsi dai pe- il ruolo dei programmatori.
ricoli e dai costi della codifica. Chi avrà ragione? Sarà politicamente troppo
È interessante notare però, tra le motivazioni corretto, ma forse potrebbero averla entram-
citate, il fatto che la presenza di molti diver- bi gli approcci, in quanto MDA è sicuramen-
si linguaggi e piattaforme di sviluppo viene te più adatto per i grossi progetti, mentre le
ormai vista come un dato di fatto non supe- metodologie agili possono essere vincenti per
rabile. L’obiettivo non è più, quindi, quello di applicazioni medio-piccole.
trovare un linguaggio migliore degli altri, che Non è escluso, poi, che non si possano coglie-
possa imporsi come standard, quanto quello re spunti da entrambi gli approcci. Per even-
di trovare un modo per svincolare l’applica- tuali approfondimenti vi rimando al sito uf-
zione dal linguaggio sviluppato. ficiale, ovvero www.omg.org/mda.

N. 66 - Novembre/Dicembre 2005 VBJ 51


REPORTAGE

Il nuovo umanesimo
tecnologico
a cura di Alberto Rosotti in maniera crescente sulla vita dell’uomo, dal
momento che l’uomo è il fulcro dell’impresa
competitiva. Ciò che ha più colpito dell’uomo
L’ing. Umberto Paolucci, Senior Chairman
Paolucci è stata la sua umiltà, dote ormai rara
di Microsoft Europa, Medio Oriente e Africa
nei manager di successo. Invitato a parlare,
e Vice President Microsoft Corporation, è Paolucci ha rotto il ghiaccio esordendo: “Per
stato ospite dei Giovani Imprenditori di As- essere credibile davanti ad un pubblico di
sindustria nel corso di un dibattito dal tema giovani devo essere come loro, quindi per-
“Il nuovo umanesimo tecnologico” tenuto il mettetemi di togliere giacca e cravatta. Il mio
16 settembre presso Assindustria di Pesaro. amico Bill si mette sempre comodo prima di
Dal suo osservatorio privilegiato Paolucci ha parlare ai giovani, la platea che preferisce”.
illustrato l’attuale scenario della globalizza- Un incipit semplice, seguito da una “lezione”
zione, i rapporti umani, la comunicazione, che ha catturato gli astanti. Ciò che segue
la formazione e la ricerca. L’impatto della è la trascrizione integrale, fatta eccezione
globalizzazione e delle moderne tecnologie è per minimi adattamenti giornalistici, di un
fonte di grandi cambiamenti che devono essere discorso appassionante durato più di un’ora
vissuti dalle imprese consapevolmente. L’in- e ricco di ottimismo; un esempio illuminante
contro di questi due fattori incide ed inciderà ricco di spunti sui quali riflettere.

Il tema che ci vede qui riuni-


ti è entusiasmante: vi parlerò
innanzitutto del nuovo mondo,
per il quale sto lavorando da 35
anni, poi parlerò dell’Europa e
dell’Italia che mi sta a cuore in
modo particolare e per termi-
nare parlerò dell’uomo, che è la
cosa in cui dobbiamo credere di
più. Ma andiamo per ordine.

Il nuovo mondo

Cominciamo dal software.


Sono convinto che oggi, dopo
tanti anni d’evoluzione, siamo
arrivati ad un punto in cui si
Alberto Rosotti è consigliere dell’Ordine degli Ingegneri di Pesaro- possono fare cose inimmagina-
Urbino e dirigente sistemi informativi presso il gruppo di mobilifici bili, un punto in cui la comples-
FBL - Della Rovere.
sità si riesce a delegare al sof-

52 VBJ N. 66 - Novembre/Dicembre 2005


REPORTAGE

tware e non alle persone. Questo è l’obiettivo zione, al lavoratore, alla conoscenza, e possia-
che abbiamo e l’obiettivo della mia azienda mo farlo con professionalità che prima non
in questi anni è stato quello di dare maggio- esistevano; si sono creati degli stili di vita
re semplicità alle cose, di dare la possibilità nuovi, degli stili di lavoro inimmaginabili fino
ad un numero sempre più ampio di persone a poco tempo fa. Avete visto, soprattutto voi
di usare questi strumenti, con un modello di giovani, la convergenza tra i diversi “ogget-
business basato su volumi alti e prezzi bassi: ti” nella loro trasformazione al digitale (come
tanti computer che costano poco, tanta gen- fotografia, video, musica); questi oggetti si ri-
te che li può avere. trovano a lavorare su piattaforme simili, si ri-
Ovviamente affinchè ciò si avveri è neces- trovano a lavorare con modalità tali che non
sario che i computer siano ragionevolmente è più un obiettivo irraggiungibile pensare di
facili da usare; di fatto il potenziale di tra- metterli insieme nelle case e nelle aziende.
sformazione che i computer hanno è diven- Questo definisce delle modalità nuove con le
tato così forte che si è creata una situazione quali viviamo la nostra giornata di persone,
di divisione tra coloro che possono avvaler- modalità nuove con le quali viviamo la no-
sene - che sanno avvalersene - e gli altri, sia stra giornata di lavoratori.
a livello di aziende che a livello di persone. Noi possiamo stabilire dove vogliamo abita-
Si è creato quindi un fossato; noi dobbiamo re, dato che è ormai semplice avere una for-
cercare di colmare questo fossato, soprattut- za lavoro globale sparsa sul pianeta, di fatto
to per coloro che, senza volerlo, stanno dalla sempre connessa alla rete. Grazie alla larga
parte sbagliata. banda condividiamo il nostro lavoro senza
Quello che si è creato è un nuovo mondo che limiti geografici.
in alcuni casi ci è sfuggito di mano; per esem- Vi do qualche dato. Le email si sono me-
pio la bolla della new economy ha proiettato diamente moltiplicate per dieci dal 1997, ed
entusiasmi eccessivi sul fatto ci fossero tan- è previsto che si moltiplichino ancora per
ti nuovi modelli di business strani, che poi cinque nel giro di tre, quattro anni. C’è una
non c’erano. Pensavamo che si potesse avere spinta su questo sempre più forte, legata alla
un enorme incremento della quantità di traf- produttività. Strumenti di questo tipo, che al-
fico telefonico, e l’effetto lento di questa “il- l’inizio erano opzionali, oggi sono indispen-
lusione” è stato la creazione di un’infrastrut- sabili perché se i miei concorrenti li usano,
tura ancora poco utilizzata, una banda larga rendono obbligatorio ciò che prima era solo
di comunicazione sulla quale si basa il no- opzionale. Semplicemente: l’asticella della
stro modo di gestire e anche di subire oggi produttività è diventata più alta.
la globalizzazione. La sfida a cui siamo chiamati è quella di gui-
La globalizzazione si è sviluppata prepoten- dare questi strumenti, vedendoli come mezzi
temente grazie al fatto che esistono le reti e mai come fini nell’ambito della concorren-
informatiche, ed esistono per tutti. Noi ab- za, per non farci superare dagli altri e, possi-
biamo creato delle porte di ingresso impor- bilmente, per essere noi a superare gli altri.
tantissime, larghissime, realizzate in un pe- Esistono ormai delle modalità operative con
riodo di ottimismo eccessivo, che oggi pos- le quali il software può accompagnare le no-
sono e devono essere date a coloro che non stre giornate, ci può gestire l’agenda in ma-
ne hanno la disponibilità. Questo è il risvol- niera raffinata, può capire cosa stiamo facen-
to positivo legato al “disincanto” della bol- do in un certo istante e quindi non interrom-
la di internet. pere il nostro lavoro, può coordinare tutte le
Quindi abbiamo un mondo globale nel qua- possibili sorgenti che abbiamo di fronte, dai
le, grazie alla tecnologia, si possono fare cose telefoni agli sms, quindi darci un insieme di
come lavorare insieme, indipendentemente stimoli produttivi ordinati e gestibili in fun-
da dove siamo, come dare valore all’informa- zione delle nostre priorità.

N. 66 - Novembre/Dicembre 2005 VBJ 53


REPORTAGE

Questi strumenti sono applicati a qualsiasi Vorrei toccare il tema dell’Europa in sen-
tipo di azienda, a qualsiasi tipo di ricerca, non so lato, perché non si può parlare di tecno-
solo nell’Information Communication Tecno- logia in Europa se non si parla della visione
logy: se noi pensiamo per esempio che la ri- che l’Europa ha di se stessa. L’Europa in que-
cerca automobilistica è basata per l’85% sul- sto momento una visione di se stessa non ce
l’uso avanzato dell’ICT, e che nella medicina l’ha. Messa in crisi nel corso del tempo, crisi
siamo al 70%, come nella biologia ed in qua- esplosa in maniera più visibile con il rifiuto di
lunque disciplina dove occorre ricerca appli- avallare la Costituzione da parte di Paesi im-
cata, comprendiamo che c’è una convergen- portanti, in primis la Francia, adesso l’Euro-
za fortissima fra ICT e scienza. pa sta cercando una visione di se stessa, deve
L’effetto netto della pervasività dell’ICT e del capire dove vuole andare. Purtroppo l’Euro-
progresso del computer è che noi tutti abbia- pa non è riuscita a darsi delle regole di gover-
mo accelerato il passo; ciò ha portato ad una nance quando era facile darsele, cioè quando
ricerca più veloce, ad una crescita maggiore, eravamo in 15; adesso siamo in 25 a lavora-
ha favorito l’occupazione e potenzialmente re con le vecchie regole, all’unanimità. Oggi
potrebbe essere ancora maggiore. Rispetto è più difficile sistemare le cose, però dobbia-
all’occupazione l’ICT è come un’onda: un’on- mo assolutamente farlo.
da lascia dietro di sé delle cose (anche nega- Vorrei spezzare una lancia sull’idea di non
tive) ma davanti a sé crea delle opportunità. buttarla via l’Europa, perché credo che sia
Quello che – in molti casi – abbiamo già visto un’ottima opportunità per tutti: l’Italia ad
nei secoli scorsi. esempio da sola non può competere, pertan-
La velocità alla quale ci siamo abituati, che è to sarà meglio che si inserisca in un sistema.
cresciuta relativamente nell’ultimo secolo, oggi Per l’Italia e per altri paesi è indispensabile
è diventata tre volte, quattro volte superiore e arrivare alla convinzione che la nostra strada
noi ci ritroveremo nel 2030 in un mondo mol- per la crescita e lo sviluppo passi prevalente-
to diverso da quello di adesso. Se siamo stati mente dall’Europa.
per quattro secoli, dal cinquecento in avanti, Ma permettetemi di parlare un po’ d’identità.
in Europa ed in particolare in Italia, avanti a Qual è l’identità dell’Europa oggi? Andiamo
tutti, gli Stati Uniti sono stati avanti a tutti nel indietro nella storia: la Grecia, Roma, l’idea
secolo scorso. Cosa accadrà nei prossimi anni? di uguaglianza, di fratellanza che è venuta dal
Se paesi emergenti o già emersi come la Cina mondo laico, poi cristiano, i nuovi valori che
e l’India riusciranno a proiettare quello che già sono venuti fuori dal Medioevo, dal Rinasci-
si vede oggi, avremo davanti un secolo - o per mento, l’illuminismo, la rivoluzione francese
lo meno una metà di secolo - nel quale saran- e a seguire quello che è successo nell’800 con
no loro ad avere un ruolo preminente. le guerre ed il sangue che ci ha portato dove
siamo arrivati adesso, agli Stati che abbiamo
L’Europa e l’Italia adesso, con forti ideali di democrazia, libertà.
Non possiamo dimenticare tutto questo.
Qui dobbiamo decidere, ed entro nel tema Voglio condividere con voi la mia visione e
dell’Europa, se questi strumenti, se le nuove la mia esperienza leggendovi una frase che ha
tecnologie, sono così forti, se hanno cioè un scritto il sociologo Domenico De Masi, che ap-
potenziale così forte da cambiare le cose. Dob- plica questo pensiero ai Paesi di cultura gre-
biamo cercare di capire se queste cose sono co-latina; dice: “ la nostra naturale inclinazio-
per noi - in Europa - una arma competitiva ne all’interclassismo, alla separazione dei po-
oppure un boomerang. In questo momento teri, alla tolleranza, alla solidarietà, alla fles-
l’ICT per l’Europa sembra un boomerang che sibilità, alla sensualità, all’allegria, all’estro-
ci sta arrivando sulla fronte, non solo nell’am- versione, alla prevalenza dei bisogni radica-
bito della tecnologia. li dell’amicizia, del gioco e della convivialità,

54 VBJ N. 66 - Novembre/Dicembre 2005


REPORTAGE

dei bisogni di ricchezza e di dominio”. Ecco concorrenti, perché perdiamo terreno, perché
ciò che siamo. la nostra capacità di produrre non ha tenuto il
Questi concetti non sono applicabili alla passo. Quindi certamente dobbiamo darci da
realtà americana, dove la carriera è la prio- fare di più, esplorare tutte le strade, non but-
rità; in Europa la priorità è la famiglia. Non tare via niente per raggiungere i nostri obiet-
voglio dire chi sia nel giusto o chi sbagli, ma tivi futuri, che non sono maggiore disoccupa-
mi permetto di sottolineare di fronte a voi che zione o i figli che stanno peggio dei padri, ma
gli europei sono coscenti di chi e cosa sono. esattamente l’inverso.
Per questo, forse, di fronte al cambiamento Quando abbiamo delle situazioni facili da
noi cerchiamo di cambiare il meno possibile, raggiungere o - come dicono gli americani - “i
cerchiamo di conservare il livello di benesse- frutti bassi”, non li raccogliamo. Ad esempio,
re che abbiamo. il turismo. Il turismo è un frutto basso per
Ma oggi se non abbiamo idee ambiziose l’Italia: il 60-70% del patrimonio mondiale è
rischiamo di perdere. Oggi spesso L’Italia qua; ma la Spagna ci ha battuto.
ed anche l’Europa è vista in chiave mera- Queste cose non le possiamo più accettare.
mente politica, un paese che non ha deci- Dobbiamo capire che cosa ci serve per vin-
so cosa vuole fare. L’Europa era partita alla cere, qual è lo scenario nel quale l’Italia può
grande con la strategia introdotta dai temi vincere. Dobbiamo fare in modo che coloro
di Lisbona, la strategia che l’Europa aveva che ci guidano abbiano chiara questa visio-
adottato negli anni dell’ottimismo, all’inizio ne, dobbiamo fare in modo che le domande
del 2000, per creare l’economia della cono- che gli imprenditori si fanno abbiano una ri-
scenza più dinamica e competitiva al mon- sposta, dobbiamo avere una visione su ciò che
do. Purtroppo dal 2000 ad oggi ci siamo ac- vogliamo essere.
corti che siamo invece andati indietro. Ora Io sono un uomo di business, non sono io
dobbiamo riprendere quasta strada: la stra- che devo dare una risposta se non per le com-
tegia di Lisbona era basata sulla Informa- ponenti che mi riguardano. Certamente sto
tion Technology come anche l’economia del- cercando di offrire il mio punto di vista a co-
la conoscenza: noi dobbiamo vincere que- loro che hanno l’obiettivo politico, nel senso
sta corsa puntando sull’innovazione, sulla più nobile della parola, coloro che devono in-
conoscenza, sul valore, caratteristiche che dicarci la strada. Non possiamo assistere ad
abbiamo e sulle quali non ci dobbiamo ar- uno scenario nel quale i Paesi che costano di
roccare. Non possiamo vincere sul prezzo o meno in tutto quello che fanno, come la Cina
sul massimo ribasso. e l’India, diventino anche i più bravi nell’in-
Pensiamo al mondo dell’islam, quanto arroc- vestire sulla ricerca, abbiano gli ingegneri mi-
cato spesso sia nella difesa della sua cultura. gliori dei nostri, siano il punto di attrazione
Io non riesco a fare affari con una persona degli investimenti.
che tiene troppo alla sua religione; noi dob- La Microsoft - sono fiero di comunicarlo - a
biamo essere invece interoperabili. I Cinesi dicembre inaugurerà un centro di ricerca di
ad esempio hanno la loro religione ed hanno base a Trento, realizzato con l’università di
anche il loro modo di lavorare ma sono molto Trento. Vi assicuro che non è stato facile far-
interoperabili e ci stanno battendo. lo in Italia. Da alcuni anni Microsoft ne ha
La separazione tra il business, lo Stato, la realizzato uno ben più grande in Cina, a Pe-
Chiesa, la religione sono dogmi ai quali siamo chino, ed uno in India, con minor difficoltà.
abituati e con i quali dobbiamo fare i conti. Ecco la partita che ci giochiamo. Dobbiamo
L’Italia sta andando male, lo dimostra la no- fare in modo che esista una strada, un piano
stra percentuale nell’ambito dell’economia per il nostro Paese che risolva i problemi che
mondiale; stiamo andando indietro, veniamo abbiamo citato. Ormai di fotografie della si-
diluiti nel PIL mondiale perché entrano altri tuazione e di diagnosi ce ne sono infinite; lo

N. 66 - Novembre/Dicembre 2005 VBJ 55


REPORTAGE

stesso Presidente Montezemolo vi ha parla- devono essere i nostri stendardi. Dobbia-


to sicuramente di queste cose, ma di terapie mo smetterla di accettare l’emorragia che
possibili non ce ne sono poi tante, quindi noi ci fa perdere le persone, la cosiddetta fuga
dobbiamo pretendere che queste “terapie” ci dei cervelli.
vengano indicate. Il limite della nostra crescita sono le perso-
Io credo che i temi di cui parlo siano temi ne: la capacità di portare a termine un pro-
di lunga gittata, la strategia di Lisbona che getto non dipende tanto dalla quantità di
possiamo riassumere come “capitale uma- soldi investiti nella ricerca ma piuttosto dal
no, infrastrutture, conoscenze” è una cosa talento delle persone coinvolte nella ricer-
che dà frutti nel tempo, però se non si co- ca. Abbiamo tanti esempi di ragazzi italiani
mincia mai non si arriva mai, quindi bisogna che vanno in America, per fermare l’emor-
lavorare per il lungo periodo. L’imprenditore ragia dobbiamo ricostruire un ecosistema
se ne rende conto immediatamente, sa che che tenga conto di come siamo, del tipo di
servono certezze sul lungo periodo, pertanto aziende che abbiamo, del tipo di università
è necessario che ci sia una condivisione po- che abbiamo, e decidere quali siano le prio-
litica su alcuni temi centrali che sono quel- rità di lungo periodo. Altrimenti le persone
li della ricerca, dell’innovazione, del capita- non hanno più fiducia.
le umano, e che ci sia garanzia di lungo pe- Bombardare i giovani con messaggi depri-
riodo sulle cose che portano il nostro Paese menti non si può, bisogna cambiare le cose
verso il futuro. fornendo contributi positivi, in particolare nei
Abbiamo bisogno che questi temi siano momenti di crisi in cui questi contributi rap-
compresi e quindi io spendo un poco di tem- presentano qualcosa di concreto. A me non
po anche per parlare di questi argomenti. sta bene che l’Italia vada indietro, bisogna
Secondo classifiche fatte su base mondiale, dare delle priorità e fare delle scelte, come
l’università italiana è al 121° posto. Le uni- in una azienda.
versità devono competere sulla base dell’ec- Leggevo recentemente che un ragazzo ame-
cellenza non sulla base dell’ubiquità. L’uni- ricano di livello scolastico non eccellente ave-
versità italiana non ha obiettivi di eccellenza. va possibilità di carriera maggiori rispetto ad
Dobbiamo pretendere una partnership forte un genio in Cina; adesso non è più così, ades-
fra università ed impresa, ci deve essere una so un genio in Cina ha più possibilità di quel-
osmosi, una condivisione della finalità della le che aveva prima. Ed in Cina di genî pro-
ricerca tra imprese ed università, soprattut- babilmente ce ne sono tanti altri, quindi non
to verso le imprese medie e piccole che non dobbiamo perdere tempo.
hanno capacità di fare ricerca, che non hanno Sembra assurdo parlare di crescita dell’oc-
capacità di guardare oltre l’orizzonte di bre- cupazione quando oggi un imprenditore che
ve. L’università deve avere un valore, deve può va ad investire in altre parti, de-localiz-
avere una ricaduta imprenditoriale, questa za. Una impresa deve fare ciò che è giusto per
deve essere la misura del suo successo, in l’impresa, però un sistema Paese deve trova-
modo che l’università sia una benedizione re una strada comune con l’obiettivo finale di
in termini di creazione di posti di lavoro, in mettere insieme i nostri punti di forza in un
tema di creazione di imprese. Microsoft ha profilo, in una miscela vincente settore per
un centro di ricerca a Cambridge; intorno a settore. Alcuni punti di forza li abbiamo solo
Cambridge c’è un fiorire di imprese che na- noi e possiamo vincere. Purtroppo dovremo
scono dall’università e qui fiorisce l’eccel- renderci conto che qualche settore lo dovrem-
lenza e la meritocrazia. mo perdere, perché per fare bene alcune cose,
In Italia i cervelli di qualità non manca- altre ne dovremo dismettere. Dobbiamo darci
no, dobbiamo fare anche noi i campioni del delle identità, dei brand che siano vendibili e
mondo, quindi meritocrazia ed eccellenza possano avere successo.

56 VBJ N. 66 - Novembre/Dicembre 2005


REPORTAGE

L’uomo e l’umanesimo tecnologico anche della grande responsabilità da assume-


re. Immaginate i danni che può fare un ma-
L’uomo è al centro di tutto, le cose dette fi- nager che dà messaggi sbagliati ai suoi, che
nora sono importanti ma contano relativa- gli smorza gli entusiasmi, che uccide la crea-
mente poco rispetto all’uomo che c’è dentro, tività, che danneggia l’autostima. Di questo
in particolare la categoria dei giovani. Chi dobbiamo renderci conto fino in fondo, per-
ha in mano le cose che contano - per esem- ché altrimenti noi, i nostri collaboratori e le
pio la tecnologia – deve saper parlare ai gio- nostre aziende non vanno da nessuna parte.
vani. La Microsoft è fatta di giovani, mentre Le cose più importanti per un manager sono
le forze politiche spesso non parlano ai gio- tre: la crescita dell’azienda, la crescita delle
vani. La Confindustria è un punto di grande persone e la crescita della soddisfazione dei
eccellenza, riesce a lavorare con i giovani, a suoi collaboratori. Queste tre cose sono col-
dargli spazio e tenerli nel sentiero principa- legate tra di loro, ed il giudice di questo non
le. Dobbiamo fare in modo che a nessun gio- sono i capi superiori: sono i collaboratori stes-
vane venga detto “devi cercare lavoro altrove si che devono aiutare il loro capo ad essere un
se vuoi scappare da un declino”. capo migliore, che devono guidarlo, che de-
I Giovani vanno attirati con una visione, vono dire quello che non va bene, perché è
con entusiasmo, con un obiettivo raggiungi- facile lamentarsi ma serve a poco. Quindi bi-
bile che non sia una sciocchezza. Se non c’è sogna che ciascuno di noi - anche rischiando
un obiettivo capace di entusiasmare le per- - contribuisca al miglioramento dell’ambien-
sone - io lo vedo in Microsoft - che sia capa- te nel quale lavora, perché nessuno può ave-
ce di catalizzare gli entusiasmi che hanno, ti- re niente per niente. Noi dobbiamo meritar-
rare fuori le energie che hanno e che spesso ci un lavoro migliore ed un capo migliore, il
non sanno neanche di avere, non si va da nes- nostro stesso successo.
suna parte. Bisogna che prendiamo in mano Molti studi dimostrano che le aziende che
la responsabilità che abbiamo perché lo sce- lavorano veramente sui valori hanno più suc-
nario che ci troviamo di fronte è di cambia- cesso e crescono più delle altre. Se solo guar-
mento; ci sono delle indagini che dicono che dassimo come si vive dentro queste aziende,
oggi un giovane di 25 anni quando avrà fini- le cose che si fanno, come si passa la giorna-
to di lavorare avrà cambiato lavoro 15 volte. ta, non c’è proprio confronto con il nostro con-
Quindi bisogna fare in modo che si capisca testo. In Italia ad esempio siamo più concen-
a cosa va incontro, per poter vivere con suc- trati sui processi, le procedure, sulla catena
cesso questo cambiamento, essere flessibile di comando e controllo; si cerca di prevedere
e diventare davvero l’architetto della propria tutto ciò che è prevedibile: in questo caso fai
vita. Serve potere guardare al lungo anziché così, in quell’altro fai cosà, ma in quell’altro
al breve, a capire quello che è importante ri- caso ancora - a cui nessuno aveva pensato -
spetto a quello che è urgente. È necessario come ti comporti se non hai un riferimento
potere costruire le pietre angolari sulle qua- valoriale? Se non c’è una cultura aziendale
li edificare il resto della casa; ci deve essere che ti possa guidare, per la quale puoi dare,
passione, divertimento, attrazione ed anche una volta che l’hai capita, il meglio di quel-
sacrificio, oltre al lavoro duro. lo che hai dentro, ed anche di più, scopren-
Se una persona non ha la possibilità di vi- do con meraviglia che non sapevi di poter
vere bene nell’azienda ha tre possibilità: o si dare di più, non valorizzi te stesso. In questo
rassegna, o cambia l’azienda da dentro oppure modo posso condividere con voi ancora una
cambia azienda. La prima possibilità, rasse- volta i valori nei quali io sto vivendo in Mi-
gnarsi, non la consiglio e dico a chi ha la pos- crosoft, valori nei quali ogni persona crede,
sibilità di guidare gli altri come i manager, di valori verso i quali ogni persona riporta siste-
essere consapevoli del privilegio che hanno ed maticamente il suo progresso.

N. 66 - Novembre/Dicembre 2005 VBJ 57


REPORTAGE

Se diamo ad un persona un obiettivo che non nascondersi nella complessità ma ridur-


non è solo quello di raggiungere il suo fattu- re le cose in termini semplici, perché le per-
rato, otteniamo la crescita personale ed il ri- sone possano capirle, possano condividerle,
spetto dei valori. I valori principali sono: l’in- possano viverle insieme. Quindi non nascon-
tegrità, l’onesta, la passione per quello che si dersi ma chiarirsi. La semplicità, la convin-
fa e la passione nel farlo insieme agli altri e zione di quello che si fa e l’autenticità sono
nel farlo per gli altri, il rispetto e l’apertura - valori basilari: non si può simulare per molto
che non sono necessariamente la stessa cosa tempo, bisogna essere convinti delle cose che
- perché io posso essere aperto e brutale ver- si fanno, bisogna essere autentici. Le perso-
so una persona oppure aperto e rispettoso. Io ne di fronte a noi sono il nostro comune de-
preferisco dire ad un collaboratore che non ha nominatore, quindi dobbiamo rendere le cose
svolto bene il suo lavoro in maniera rispetto- semplici per poter parlare ed agire in modo
sa, costruttiva, perché l’obiettivo è farlo vive- comune. La tecnologia, anche la più compli-
re meglio e di più insieme a me. Mi impegno cata, l’obiettivo più raffinato, il messaggio più
a rendere gli altri migliori quindi a vivere il difficile, devono essere assolutamente com-
successo degli altri: il successo di un mana- prensibili, a misura dell’uomo che abbiamo
ger non è il suo, ma quello delle persone che di fronte perché in tutti i possibili messaggi
gestisce, la capacità di prendersi grandi sfi- si mantenga il rispetto, l’equilibrio e l’integri-
de e saperle vivere ogni giorno, spezzettarle tà della persona.
in pezzi eseguibili nei quali si possa vedere Poi il grande valore della diversità. Una cosa
ogni giorno l’autocritica. bella tra le tante che ho vissuto è quella del
Occorre saper mettere in dubbio le certezze tirare fuori il valore della diversità: punti di
consolidate: io dico sempre a nostri ragazzi di vista diversi, persone diverse, obiettivi diver-
non essere allineati ma di cercare di genera- si, storie diverse, paesi diversi e anche sempli-
re un po’ di caos costruttivo, perché se siamo cemente uomo verso donna. La donna spesso
tutti d’accordo e si passa la maggior parte del è discriminata perché viene tenuta indietro,
tempo a cercare di capire cosa il capo pensa perché giustamente ha delle priorità diver-
e vuol sentirsi dire - come spesso succede in se dagli uomini nella vita. Quindi tirar fuo-
molte aziende - allora andremo a finire tutti ri il valore dalle donne è complesso e molte
verso il muro. aziende non sono capaci di farlo. Quando si
Occorre mettere impegno verso l’eccellen- parla di diversità non è un discorso di tolle-
za, capire quello che si può fare meglio, de- rarla, perché tollerare è “accetto, però un po’
dicare impegno per i risultati, per la quali- mi da fastidio”, bensì bisogna valorizzare la
tà; chi è in una posizione di particolare forza diversità.
deve essere particolarmente attento nel do- Poi se posso permettermi un altro suggeri-
sare la sua forza, nel rispettare i concorren- mento: cercare di non essere monomaniaci,
ti, nel creare spazi anche per gli altri. Micro- monocordi, monotematici, totalmente focaliz-
soft dosa continuamente la sua forza perché zati su una cosa. Certo, soprattutto quando
se le sue innovazioni fossero troppo invasi- una azienda è leader di settore, ha bisogno
ve potrebbero avere un effetto brutale, mal di persone che siano altamente specializzate
accettato sia dai concorrenti che dalle per- e paranoiche in quello che fanno, però non
sone in genere. basta. Bisogna lavorare con gli altri, bisogna
essere aperti, avere altri interessi, essere del-
La complessità, la semplicità, le persone vere a 360 gradi, essere delle per-
la diversità e la compassione sone che sanno stare con gli altri. Una bella
parola è “compassione” che significa avere
Affrontiamo adesso il grande tema di ridur- passione insieme agli altri ma anche com-
re la complessità verso la semplicità, ovvero passione degli altri. E qui irrompe anche il

58 VBJ N. 66 - Novembre/Dicembre 2005


REPORTAGE

tema dell’autostima, il tema della difficoltà I protagonisti di questo cambiamento sono


che gli altri possono avere ed anche il tema inevitabilmente i giovani e credo che si deb-
della compassione di se stessi. È lecito che ba identificare un insieme di forze positive
io mi ponga degli obiettivi irraggiungibi- per il cambiamento, in qualunque realtà, in
li che distruggano la mia vita? Posso accet- una realtà aziendale, in una realtà di associa-
tare il rischio se sono convinto di farcela - zione, di federazione, come in una realtà po-
però se poi in realtà non ci arrivo distruggo litica. Un insieme di forze che operano per i
la mia vita e quella di chi crede in me; allo- cambiamenti in una direzione nella quale c’è
ra meglio essere realistici fin dall’inizio: que- una terapia condivisa. Serve che lo facciano
sto è il tema della compassione e della com- con determinazione, con convinzione, con
prensione di se stessi. Certo ci vuole anche spirito di servizio, con umiltà, con autentici-
la paranoia: molte aziende di successo sono tà, con rispetto, con fiducia, con umiltà e con
nate anche dalla paranoia, dalla forza, dalla fede nel futuro.
capacità di lavorare duro, dalla capacità di Credo che il nostro compito sia avanzare ver-
concentrarsi del loro leader. Però il successo so un mondo migliore di quello che noi ab-
deve essere anche accompagnato dalle altre biamo trovato, creare opportunità per gli al-
cose. Io credo che noi possiamo cambiare - tri, generare un cambiamento positivo; voglio
non in tempi brevissimi - questo scenario, se concludere con una frase, citando una canzo-
avremo la fortuna di essere guidati dai lea- ne di Bono Vox, “Un uomo viene per cambiare
der giusti con i programmi giusti. Ma certa- le cose”. Io credo che noi non siamo qui per
mente non cambieremo governing di notte, accettare passivamente quello che accade, ma
ci vorrà tempo. siamo qui per cambiare le cose.
I N O F F E R TA V B J 6 6
Scrivi a
Imperfect XML Rants, XML in a Nutshell,
Raves, Tips, and Tricks ... book@infomedia.it Third Edition
from an Insider specificando di E. Harold
di D. Megginson W. Scott Means
nell’oggetto della
Prentice Hall
e-mail: O’Reilly
ISBN 0131453491
256 pp - 35,95 €
IN OFFERTA ISBN 0596007647
712 pp - 39,95 €
VBJ n. 66
OPPURE
inviaci il coupon
Pro MSMQ: Core C# and .NET
Microsoft Message sottostante The Complete and Com-
Queue Programming al numero di fax prehensive Developer’s
di A. Redkar et al. Guide to C# 2.0 and .NET 2.0
0587/732232 di S. Perry

Apress Potrai acquistare Prentice Hall


ISBN 1590593464 ISBN 0131472275
423 pp - 50,24 €
i libri qui riportati con 1008 pp - 46,95 €
uno
SCONTO
Model Driven Architecture
ECCEZIONALE Model-Driven Software
Foundations Development
and Applications del 10% anche se di S. Beydeda et al.
di A. Hartman
D. Kreischei
acquisti solo un
libro
Springer Springer
ISBN 3540300260 OPPURE ISBN 354025613X
349 pp - 55,64 € 464 pp - 85,55 €
del 20% se acquisti
3 libri

VBJ 66
.NET TOOLS
Mail2Rss RSS. La particolarità dell’applicazione consiste
di Raffaele Di Natale nel fatto che i messaggi elaborati restano anco-
ra non letti per l’utente che successivamente li
Posta elettronica e news feed in formato RSS 2.0: apre tramite un normale client di posta elettro-
due modi differenti di distribuire informazioni, nica. Si tratta di un web service .NET sviluppa-
ma che grazie a Mail2Rss possono interagire in to in C# basato su due moduli denominati ri-
totale sicurezza consentendoci di trarre il massi- spettivamente mai2rss.dll e Org.Mentalis.Secu-
mo dalle due tecnologie. rity.dll [2]. Il primo rappresenta l’applicazione
principale; il secondo gestisce gli aspetti lega-
Immaginiamo una casella di posta elettronica ti alla sicurezza nella connessione ed è un mo-
utilizzata da un gruppo d’utenti come una sorta dulo esterno.
di repository di novità e aggiornamenti vari da L’applicazione gira in ambiente Microsoft Win-
condividere quotidianamente. Supponiamo inol- dows 2000 Professional/Server, Windows XP Pro-
tre che gli utenti non vogliano ricevere i messag- fessional, Windows 2003 Server con IIS 5.0 e .NET
gi inviati dal resto del gruppo all’interno della Framework 1.1.
propria casella, ma semplicemente vogliano vi- È necessario predisporre almeno un account tra
sualizzarli tramite una pagina web. In altre pa- POP3, Passport-MSN, Yahoo o GMail. Il file XML
role vorremmo che i messaggi di posta elettroni- prodotto dal servizio va poi manipolato median-
ca fossero semplicemente “visti” in maniera dif- te un software idoneo all’aggregazione di news
ferente e distribuiti in un formato standard solo feed: il tool è stato testato con SharpReader [3],
se richiesti (come il testo che scorre in una por- FeedReader [4] e FeedDemon [5], ma funziona
zione della home page del gruppo di utenti, per correttamente anche con altri news aggregator
esempio). Mail2Rss è proprio lo strumento adat- come RSSBandit [6]. L’applicazione descritta in
to a risolvere questo particolare tipo di proble- quest’articolo è stata installata su Windows XP
ma e non solo. SP2 con IIS 5.0, .Net Framework 1.1, Internet
Explorer 6.0.
Un cenno su RSS 2.0
Installazione
RSS 2.0 [Really Simple Syndication] è un for-
mato orientato alla distribuzione d’informazioni La procedura d’installazione è sorprendente se
sul web (content syndication) basato su un dia- pensiamo di aver a che fare con un tool com-
letto di XML [1]. Un documento RSS è costituito pletamente gratuito. Dopo aver portato a termi-
da un elemento <rss> che specifica la versione, ne il download dal sito [7] basta seguire il wi-
in questo caso la 2.0, ed un elemento <channel> zard che in pochi passi effettua l’installazione
che contiene tutte le informazioni sui metadata del web service con relativa creazione della di-
ed i loro contenuti. rectory virtuale all’interno della cartella Inetpub
Mai2Rss v.07 esegue una conversione dei mes- di default. Nel caso in cui la cartella Inetpub non
saggi di posta elettronica, presenti all’interno di dovesse coincidere con quella dell’installazio-
una prefissata casella, aggregandoli in formato ne, l’unico modo è quello di eliminare in IIS la

N. 65 - Settembre/Ottobre 2005 VBJ 61


.NET TOOLS

directory virtuale presente e ricrearla in corri- l’interno della casella è presente un solo mes-
spondenza della locazione preferita, ricopiando- saggio così costituito:
vi il contenuto della vecchia cartella. Una volta
installata è possibile rimuoverla dal pannello di 1. Nome mittente: Paolo Rossi;
controllo di Windows. Al termine dell’installa- 2. Indirizzo: rossi.paolo@dominioposta.it
zione Mail2Rss può essere richiamata digitan- 3. Oggetto: Test Mail2RSS
do ad esempio http://localhost/mail2Rss/ se lo- 4. Corpo del messaggio: Prova per Mail2Rss.
calhost è il web server in cui abbiamo installa- 5. Allegato: allegato1.doc
to il web service.
il corrispondente file xml visualizzato è così
Criptare la password strutturato:

All’interno della home page è presente una se- <?xml version=”1.0” encoding=”utf-8”?>
zione “Encrypt the password” che consente al- <rss xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
l’utente di criptare agevolmente la password rela- xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
tiva al proprio account di posta. Prima di lanciare version=”2.0”>
il web service è necessario infatti criptare la pas- <channel>
sword, in quanto il servizio è richiamato tramite <title>RSS 2.0 email feed from dominioposta.
una richiesta http di tipo get con testo in chiaro it</title>
e quindi facilmente intercettabile. Dopo aver in- <link>http://mail2rss.sourceforge.net</link>
serito all’interno della testbox “password” la pas- <description>RSS 2.0 email feed from
sword ed aver premuto il tasto “Encrypt” sarà dominioposta.it</description>
visualizzata una stringa che rappresenta appun- <generator>mail2rss v0.7</generator>
to la password criptata attraverso i servizi speci- <copyright>Copyright (C) 2004 by Charlie
fici dell’applicazione. Kostov</copyright>
Mail2Rss può essere utilizzata senza alcuna va- <ttl>60</ttl>
riazione dei parametri di default: la home page <language>en-us</language>
descrive sinteticamente la modalità d’utilizzo del <lastBuildDate>Sat, 22 Oct 2005 16:40:10
servizio. Si supponga che l’account di posta uti- GMT</lastBuildDate>
lizzato sia di tipo Pop3, con username = nomeu- <item>
tente, password = miapassword e server POP3 = <title>Test Mail2RSS</title>
dominioposta.it. Seguendo le indicazioni dell’ho- <link />
me page, per ottenere le news feed relative alle <description>Prova per Mail2Rss ===[ mail2rss
email presenti all’interno dell’account d’esempio detected attachment(s) list ]====== Attachment
digitiamo sul browser: filename: allegato1.doc </description>
<author>”Paolo Rossi” &lt;
http://localhost/mail2rss/mail2rss.asmx/GetMail?mail paolo.rossi@dominioposta.it&gt;</author>
Server=dominioposta.it&userID=nomeutente&userPass= <pubDate>Fri, 21 Oct 2005 19:45:29 +0200</pubDate>
password_criptata <category>mail message</category>
</item>
Dopo qualche secondo d’attesa, in relazione alla </channel>
velocità di connessione, al tempo di risposta del </rss>
server, al numero di messaggi ed al contenuto de-
gli stessi, vedremo apparire un file XML in forma- Tralasciando le tipiche intestazioni XML si pos-
to RSS 2.0 che aggrega tutti i messaggi trovati. sono notare l’elemento rss, il channel con i riferi-
Nel caso in cui un messaggio preveda uno o menti all’applicazione e più in basso l’unico item
più file allegati, il loro nome verrà elencato al- di tipo mail message che rappresenta il messag-
l’interno della news relativa. Se per esempio al- gio in precedenza descritto.

62 VBJ N. 66 - Novembre/Dicembre 2005


.NET TOOLS

All’interno di tale item si riconoscono: Conclusioni


l title, l’oggetto del messaggio; Mail2Rss è un’applicazione che svolge un com-
l description, corpo del messaggio, con gli even- pito semplice, ma lo fa senz’altro in maniera
tuali allegati; soddisfacente.
l author, il mittente con nome e indirizzo; Come anticipato nell’introduzione, Mail2Rss
l pubDate, data d’invio del messaggio risolve un problema specifico, ma consideran-
do l’abuso che spesso si fa oggi con mailing
All’interno della casella di posta elettronica pos- list o strumenti simili, questo web service,
sono essere presenti più messaggi; in questo caso grazie all’interazione tra due servizi apparen-
si avrà una sequenza finita di item di tipo mail temente slegati tra loro rappresenta una vali-
message. da alternativa nella distribuzione d’informa-
Utilizzando un visualizzatore di news feed, nel zioni nel web.
nostro esempio RSSBandit, il risultato finale avrà
un aspetto simile a quello descritto in figura. Riferimenti

[1] http://blogs.law.harvard.edu/tech/rss
[2] http://www.mentalis.org/soft/projects/ssocket/
[3] http://www.sharpreader.net/
[4] http://www.feedreader.com/
[5] http://www.bradsoft.com/feeddemon
[6] http://www.rssbandit.org/
[7] http://sourceforge.net/projects/mail2rss

Prodotto
Mail2Rss
Configurazione
Url di riferimento
http://sourceforge.net/projects/mail2rss
Come detto in precedenza non è necessario va-
Stato Release
riare alcun parametro per utilizzare il servizio
v. 07
in maniera standard. In ogni caso, come in tutti
i web service .NET, il file denominato web.con-
Semplicità d’uso ★★★★✩
Eccellente la procedura d’installazione. Applicazione semplice da
fig permette di personalizzare la configurazione
usare. L’unica limitazione è legata alla necessità di modificare ma-
dell’applicazione. È possibile variare il nume- nualmente l’indirizzo di connessione. Nella prossima release sarà
ro massimo di messaggi elaborati per ogni ac- fornito un supporto per testare i parametri di connessione.
count, la dimensione massima del singolo mes- Utilità ★★★★✩
saggio e gli indirizzi standard per i gateway rela- L’applicazione del servizio avviene in una nicchia della distribuzio-
tivi ai principali servizi di webmail come yahoo, ne dell’informazione. Risolve in maniera soddisfacente il proble-
msn, hotmail. Sempre all’interno del file di con- ma di pubblicare come news feed RSS i messaggi di un dato ac-
count di posta elettronica.
figurazione si può modificare la chiave utilizza-
ta per crittografare la password, creandone una Qualità prodotto ★★★★✩
personale. Buona, nei test effettuati il servizio ha sempre completato il suo
compito nonostante alcuni casi di lentezza nella connessione al
La visualizzazione delle news feed può avvenire server di posta. Sono gestiti anche gli eventuali errori di connes-
offline utilizzando un tool specifico oppure online. sione al server di posta.
Nel secondo caso la strada senz’altro più agevole Qualità documentazione ★★★✩✩
è quella di utilizzare i moduli standard, presenti Scarsa, se si eccettua la documentazione della home page del
ormai nella maggior parte dei CMS, atti alla visua- servizio
lizzazione di news feed da un URL specifico.

N. 66 - Novembre/Dicembre 2005 VBJ 63


.NET TOOLS

DevPartnerProfiler Per attivare la procedura di raccolta dei dati, è suf-


di Fabio Perrone ficiente selezionare la voce di menu che abbiamo
menzionato in precedenza e premere Ctrl+F5 per
Uno strumento gratuito per misurare le presta- avviare l’applicazione senza debug – ciò non perché
zioni di applicazioni .NET il programma non sia in grado di raccogliere dati
anche in sessioni di debug, ma perché ci sono meno
Considerare le prestazioni quando si scrive del co- dati da raccogliere e meno interferenze. Una volta
dice dovrebbe sempre essere una priorità per ogni lanciata l’applicazione, è possibile effettuare qual-
programmatore che si rispetti. Il problema è che siasi genere d’operazione che si desidera, tutto sotto
non sempre si possiedono le conoscenze necessarie l’“occhio vigile” di DevPartner Profiler che registre-
o una quantità sufficiente di tempo a disposizione rà (senza che lo sviluppatore se ne accorga, e quindi
per risolvere il problema alla radice, vale a dire scri- abbastanza rapidamente) ogni singola operazione ef-
vere codice che utilizzi le migliori pratiche offerte fettuata. Per ultimare l’analisi è sufficiente termina-
dal linguaggio in cui si sta sviluppando, per ottene- re l’applicazione, ottenendo così, direttamente nel-
re applicazioni prestazionalmente soddisfacenti. È l’IDE di Visual Studio.NET, un file con estensione
ovvio che in applicazioni particolarmente comples- .dpsession che conterrà una notevole mole d’infor-
se le cattive prestazioni di un programma non di- mazioni, utili per capire quali metodi o addirittura
pendono solamente dal codice scritto male, ma in- quali singole istruzioni sono più lente.
fluscono negativamente altri fattori quali la lentez- I dati raccolti sulle prestazioni includono informa-
za della rete, l’accesso a database remoti e così via. zioni sugli assembly, sulle classi e sul codice sorgen-
Per ottimizzare il codice esistono tuttavia strumen- te. Una volta che si hanno questi dati a disposizione,
ti quali DevPartner Profiler della Compuware (che spetta in ogni caso al programmatore intervenire e
rientra nella categoria dei cosiddetti “Performance correggere eventuali anomalie nel codice.
analysis tool”) che possono aiutare a scoprire even- Le unità di misura delle prestazioni possono es-
tuali colli di bottiglia nell’applicazione. sere cicli macchina, microsecondi, millisecondi o
DevPartner Profiler viene installato come add- secondi, a scelta dell’utente. Le statistiche genera-
in per Visual Studio 2003, quindi lo ritroviamo li che ci vengono presentate variano a seconda se
nel menu Strumenti, sotto la voce DevPartner. si analizzano i metodi o se si analizzano le singo-
La prima operazione da fare, se si vogliono effet- le righe d’ogni metodo. Nel primo caso si ha a di-
tivamente testare le prestazioni solo della propria sposizione una grande quantità di dati, i cui prin-
applicazione, è quella di escludere il tempo tra- cipali sono la percentuale del tempo trascorso in
scorso in thread d’altre applicazioni che posso- quel metodo rispetto al tempo totale trascorso, il
no essere in esecuzione in quell’istante e consi- numero di volte che un metodo è stato chiamato, il
derare solo i thread del nostro programma. Così tempo medio d’esecuzione, l’esecuzione più rapida
facendo, i dati che saranno prodotti risulteranno e più lenta del metodo, il tempo reale impiegato,
totalmente indipendenti da ingerenze esterne. La in pratica considerando anche thread d’altre appli-
flessibilità di questo prodotto si denota anche dal cazioni (ignorando quindi l’impostazione accenna-
fatto che può raccogliere dati da chiamate effet- ta in precedenza) e il tempo percepito, vale a dire
tuate verso componenti scritti da terze parti, in- una misurazione che comprende anche il leggero
clusi componenti COM per cui non si ha a dispo- sovraccarico dovuto alla presenza di DevPartner
sizione il codice sorgente. È possibile effettuare Profiler durante l’esecuzione della nostra applica-
test sia su applicazioni Windows Forms sia su ap- zione. Nel secondo caso, cioè quando si analizzano
plicazioni Web ASP.NET, sia su applicazioni nati- le singole righe di codice, abbiamo a disposizione
ve scritte in C++ utilizzando la tecnologia ATL, il numero di volte che una riga è stata eseguita, la
con l’unica limitazione che tutto venga eseguito percentuale di tempo relativo a quella riga rispet-
su un’unica macchina, in pratica non in remoto to al metodo che la contiene, il tempo totale della
(questa opzione viene superata se si acquista la riga incluse le chiamate ad eventuali metodi e il
versione non Community del prodotto). numero di metodi richiamati da quella riga.

64 VBJ N. 66 - Novembre/Dicembre 2005


.NET TOOLS

Un ulteriore metodo visuale a nostra disposizione


è rappresentato dal grafo delle chiamate effettua- Prodotto
te verso un metodo e da quel metodo verso altri Compuware DevPartnerProfiler Community Edition
metodi: tramite i cosiddetti percorsi critici (cioè Url di riferimento
la successione di metodi figli chiamati da un me- http://www.compuware.com/products/devpartner/profiler/default.asp
todo, che hanno accumulato la maggiore quanti-
tà di memoria) è possibile mettere in evidenza i Stato Release
cosiddetti “colli di bottiglia”. Stabile

Nonostante alcune limitazioni della versione Semplicità d’uso ★★★★✩


Community, quali l’impossibilità di confrontare La gran quantità di dati analizzati richiede un piccolo sforzo per
due sessioni di test, l’esecuzione dei test all’ester- poterli interpretare al meglio.
no di Visual Studio.NET, l’obbligo dell’esecuzione Utilità ★★★★✩
delle applicazioni da un’unica macchina, DevPart- Strumento fondamentale per chi desidera migliorare le presta-
ner Profiler risulta un ottimo prodotto per chi ha zioni.
esigenze urgenti di miglioramento di prestazio- Qualità prodotto ★★★★✩
ni. Utilizzato con altri tool quali FxCop, dovrebbe
Affidabile, nei test sul prodotto eseguiti non ha mai mostrato par-
permettere di ottenere buoni risultati in poco tem- ticolari problemi.
po. È comunque bene ricordare che se le presta-
Qualità documentazione ★★★✩✩
zioni di un’applicazione vengono monitorate sin
Presente help integrato con Visual Studio.NET molto esaustivo
dall’inizio dello sviluppo, i risultati saranno de-
(in lingua inglese).
cisamente migliori che tentare di “mettere delle
pezze” ad applicazioni già ultimate.