Sei sulla pagina 1di 55

I N O F F E R TA V B J 6 9

Enterprise JavaBeans
Scrivi a Java I/O, 2ed
3.0, 5th Edition book@infomedia.it di E. Harold
di R. Monson-Haefel,
e B. Burke
specificando
nell’oggetto della
O’ Reilly e-mail: O’ Reilly
ISBN 059600978X
760 pp - 49,99 €
IN OFFERTA ISBN 0596527500
800 pp - 45,00 €
VBJ n. 68
OPPURE
inviaci il coupon
Computer Numerical Learning UML 2.0
Control:Operation and sottostante di R. Miles
Programming, 3rd
Edition
al numero di fax e K. Hamilton

di J. Stenerson
e K. Curran
0587/732232
Potrai acquistare
Prentice Hall O’ Reilly
ISBN 0131115472 i libri qui riportati con ISBN 0596009828
528 pp + cd - 85,95 € uno 286 pp - 44,99 €

SCONTO
Cryptography and ECCEZIONALE Introduction to
Network Security, Programming Using
4th Edition del 10% anche se Visual Basic 2005
di Stallings, W.
acquisti solo un di D. Schneider

libro Prentice Hall


Prentice Hall
ISBN 0131873164
OPPURE ISBN 0130306541
752 pp - 57,95 €
592 pp - 68.95 € del 20% se acquisti
3 libri

VBJ 68
online.infomedia.it
n. 69 - maggio/giugno 2006
bimestrale - anno dodicesimo

Direttore Responsabile
Marialetizia Mari (mmari@infomedia.it)
Direttore Esecutivo
EDITORIALE
Francesco Balena (fbalena@infomedia.it)
Managing Editor Informatica, università,
e il progetto S@MP
Renzo Boni (rboni@infomedia.it)
Collaboratori
Raffaele Di Natale
Maurizio Mammuccini
Fabio Perrone

D
Paolo Pialorsi
Stefano Savo a qualche tempo sono tornato in contatto con la mia vec-
Scott Swigart chia università, dove ho preso la laurea quasi venti anni
fa. È stato un bel tuffo nel passato, ma anche nel presente
e nel futuro, che mi ha portato a fare qualche considerazione
inaspettata.

La prima impressione è che vi sia ancora un certo scollamento


tra quello che si studia e la conoscenza che poi si utilizza nel
mondo del lavoro. Ma non lo dico per introdurre la solita tiritera
a proposito del fatto che “...l’università deve essere più vicina al
mondo del lavoro.” Anzi, io credo che per certi versi è il mondo del lavoro a dover essere
Direzione più vicino a quello che si studia nelle università. Mi spiego meglio.
Natale Fino (nfino@infomedia.it)
Marketing & Advertising Chi scrive codice per vivere è spesso animato dalla fretta di consegnare un software, fretta
Segreteria: 0587/736460 che spesso porta ad una analisi frettolosa e a una fase di test ancora più approssimativa.
marketing@infomedia.it A volte i risultati si vedono, sotto forma di applicazioni che vanno in errore, mostrano
Amministrazione risultati errati o addirittura corrompono i dati.
Sara Mattei
(amministrazione@infomedia.it)
Al confronto, nelle università il mondo gira al rallentatore. L’analisi viene fatta in modo
Grafica più rigoroso e soprattutto senza fretta. Magari ci si mette il doppio del tempo e il prodot-
Monica Buonamici to finale non ha le rifiniture che ci si aspetta da un software commerciale, ma lo scopo
(grafica@gruppoinfomedia.it)
non è di scrivere applicazioni da vendere. Gli studenti devono passare esami dedicati ai
database, alla programmazione ad oggetti, intelligenza e visione artificiale, compilatori,
Technical Book e comprensione del linguaggio naturale. A chi vive scrivendo gestionali alcuni di questi
Lisa Vanni (book@infomedia.it)
temi suoneranno quasi “esoterici”, ma di sicuro sono una ottima palestra e abituano a un
Segreteria rigore mentale che non guasterebbe in molte software house.
Enrica Nassi
(info@infomedia.it)
Come mettere insieme il meglio di questi due mondi? Non posso fornire una ricetta com-
pleta in poche righe, ma credo serva uno sforzo da entrambi i lati. I laureati dovrebbero
Stampa comprendere che nel mondo reale devono confrontarsi con clienti che spesso non sanno
TIPOLITOGRAFIA PETRUZZI spiegare cosa vogliono (o non lo sanno neanche loro), che il programma deve girare anche
Citta’ di Castello (PG)
su computer lenti e con poca memoria, che i linguaggi e i sistemi operativi hanno un bel
po’ di bachi, e che in definitiva hanno ancora molto da imparare su come si progetta e si
Ufficio Abbonamenti scrive una applicazione. Le aziende devono riconoscere che un curriculum universitario
Tel. 0587/736460 - Fax 0587/732232
e-mail: abbonamenti@infomedia.it può essere importante, sia per il differente tipo di know-how sia per la differente forma
www.infomedia.it mentis che si acquisisce durante lo studio di materie teoriche.
Gruppo Editoriale Infomedia srl
Via Valdera P., 116 - 56038 Ponsacco (PI) Italia Concludo segnalando una bella iniziativa di Microsoft, che tende ad avvicinare questi
Tel. 0587/736460 - Fax 0587/732232 due mondi: si tratta di S@MP (Stage at Microsoft Partner) e offre ai laureati la possibilità
red_vbj@infomedia.it di studiare da vicino le tecnologie software che useranno poi sul campo e alle aziende
la possibilità di lavorare con laureati già “skillati” su linguaggi e prodotti Microsoft. Per
Manoscritti e foto originali anche se non pubblicati,
non si restituiscono. è vietata la riproduzione
maggiori informazioni: http://www.progettosamp.it.
anche parziale di testi e immagini.
Francesco Balena
Si prega di inviare i comunicati stampa e gli inviti stampa per
la redazione all’indirizzo: comunicatistampa@infomedia.it
fbalena@dotnet2themax.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. 69 - Maggio/Giugno 2006 VBJ 
SOMMARIO
N.69
M A g g i O / g i u g n o

RUBRICHE

Editoriale 7
.NET Tools 54

SPECIALE

WinFX: Windows Communication Foundation 11


Vediamo i componenti chiave di WinFX, la prossima versione di API managed per Windows
di Paolo Pialorsi

VB6

Accesso al filesystem da Visual Basic 6 con classi .NET 21


Come accedere alle funzionalità del Microsoft .NET Framework inerenti al filesystem dalle applicazioni Visual Basic
6 esistenti, e ottenere l’estensione di un file, la parte directory del percorso o il nome del file e come scatenare eventi
quando cambia il contenuto di una directory
di Scott Swigart, Swigart Consulting LLC

ENTERPRISE

Interoperabilità COM e .NET (prima puntata) 34


Comprendere e confrontare i modelli di eventi in .NET ed in COM non solo può aiutarci a specializzare la nostra co-
noscenza del framework .NET stesso ma può essere utile per un miglior riutilizzo event-driven, in applicazioni .NET,
di software binario COM già scritto
di Maurizio Mammuccini

WEB

Analisi degli accessi ad un sito web (seconda puntata) 61


Tra i mezzi di comunicazione di massa il web è quello che meglio si presta ad essere misurato; ma quanto sono affidabili
queste rilevazioni? E qual è il loro valore?
di Stefano Savo

N. 69 - Maggio/Giugno 2006 VBJ 


WinFX

WinFX: Windows
Communication
Foundation
Vediamo i componenti chiave di WinFX, la prossima WinFX
versione di API managed per Windows

di Paolo Pialorsi

I
niziamo con questo articolo una serie di appun- famiglia Windows. È pensato
tamenti dedicati all’introduzione di WinFX. Win- per consentire la comunicazio-
FX è la sigla che identifica la prossima versione ne tra processi, macchine e si-
di API managed per Windows, cioè basate sul .NET stemi informativi anche etero-
Framework di Microsoft, che vedrà la luce verso la genei, sfruttando protocolli di
fine del 2006, insieme a Windows Vista. WinFX fun- comunicazione personalizza-
zionerà anche su Windows XP Service Pack 2 e su bili e configurabili, utilizzan-
Windows Server 2003, rendendo molto interessanti le do un’infrastruttura “plugga-
sue caratteristiche anche per chi non svilupperà da bile” di servizi e funzionalità
subito applicazioni per Windows Vista. al contorno.
Da un punto di vista pratico WinFX è un insieme • WPF (Windows Presentation
di librerie managed per la gestione delle applica- Foundation): si tratta del suc-
zioni future, che copre aree come la gestione del- cessore di GDI, sviluppato in
l’interfaccia utente, la comunicazione tra processi ambiente .NET. Fornirà tut-
e/o macchine, la gestione della sicurezza e dei flus- ti gli strumenti per la defi-
si operativi dei software che sviluppiamo. nizione grafica delle appli-
Dal punto di vista della sua architettura e composi- cazioni per Windows Vista.
zione, WinFX è costituito da tre mattoni principali: Sarà utilizzabile sia da codi-
ce, sia attraverso appositi de-
• WCF (Windows Communication Foundation): è signer che produrrano del co-
l’infrastruttura di comunicazione del futuro per la dice XAML, una grammatica
XML per la definizione di pri-
mitive grafiche vettoriali da
utilizzare in WPF.
Paolo Pialorsi è un consulente e autore specializzato nello • WF (Windows Workflow

sviluppo di Web Service e soluzioni Web con il Framework Foundation): un framework
.NET di Microsoft. Lavora nell’omonima società Pialorsi Sistemi applicativo sviluppato in co-
S.r.l. e fa parte del gruppo DevLeap. Può essere contattato via
dice managed .NET e pensa-
email: paolo@devleap.it. Paolo mantiene un blog all’indirizzo:
http://blogs.devleap.com/paolo/. to per gestire/creare work-
flow che interagiscano con i

N. 69 - Maggio/Giugno 2006 VBJ 11


WinFX

vari servizi e prodotti software Microsoft di esprimere la loro creatività, mantenen-


e con applicazioni di terze parti. I flussi do intatto il codice e le funzionalità delle
che definiremo potranno ad esempio inte- applicazioni scritte da noi sviluppatori.
ragire con la suite di prodotti Office 2007,
con il sistema operativo Windows o con In questo primo articolo ci occuperemo di
applicazioni da noi sviluppate. L’hosting WCF, sia dal punto di vista architetturale che
dei flussi sarà libero, cioè potremo ospi- operativo, implementando qualche sempli-
tare il motore di Workflow all’interno di ce servizio di prova. L’intera serie di articoli
una qualsiasi applicazione managed. Gli sarà orientata a valutare WinFX senza scen-
elementi di base di un workflow potranno dere eccessivamente nei dettagli implemen-
essere scelti all’interno di un set predefi- tativi, dal momento che il prodotto ad oggi è
nito ovvero realizzati da noi, estendendo in versione Beta 2 e potrebbe ancora cambia-
il modello ad oggetti di WF. re, in particolare nei dettagli, prima del suo
rilascio in versione definitiva.
A questi si affiancano altri strumenti e tec-
nologie orientati alla sicurezza, alla gestione Perché WCF
dei dati e alla definizione grafica dei layout Attualmente nell’ambito delle tecnologie Mi-
delle applicazioni: crosoft abbiamo diversi strumenti per realiz-
zare applicazioni distribuite e possiamo sfrut-
• InfoCard: è l’infrastruttura di sicurezza ela- tare diverse infrastrutture di comunicazione.
borata da Microsoft per offrire un meta-si- Nel caso in cui si debbano sviluppare Web Ser-
stema di autenticazione incentrato sullo vice abbiamo a disposizione ASP.NET, che con
scambio di identità digitali tra applicazio- i suoi servizi ASMX ci consente di realizzare
ni e sistemi. Il suo obiettivo è fornire uno soluzioni SOAP basate sul trasporto HTTP e
strumento sicuro e standard, a livello di in- pensate per essere interoperabili con le altre
frastruttura software, per fornire le varie ti- piattaforme. Il motore degli ASMX però non
pologie di identità associate ad un utente. è facilmente personalizzabile, occorre infatti
• WinFs: se ne parla ormai da oltre tre anni creare delle SoapExtension o dei SoapProto-
e rappresenterà il salto di qualità nella ge- colFactory per estenderlo, e non supporta tut-
stione dei contenuti sul personal computer. te le numerose specifiche del mondo WS-*,
Si tratta di un motore di indicizzazione dei come WS-Security, WS-Trust, WS-SecurePolicy,
file e dei contenuti, pensato per rendere me- ecc. In questo senso interviene Web Services
glio accessibili le informazioni presenti sui Enhancements, ad oggi nella sua versione 3.0
nostri PC. Rispetto ai file system tradizio- per .NET Framework 2.0. WSE3 offre una se-
nali consente di categorizzare le informa- rie di servizi aggiuntivi per gli ASMX di ASP.
zioni memorizzate tramite attributi definiti NET, oltre ad un’infrastruttura per l’hosting
in uno schema, per poi poterli ricercare sia di servizi SOAP che sfruttino anche protocol-
dal codice dei nostri programmi, sia dall’in- li differenti da HTTP. Nel momento in cui si
terfaccia utente di Windows. debbano far dialogare applicazioni .NET tra di
• Microsoft Expression: un insieme di stru-
loro abbiamo poi a disposizione .NET Remo-
menti (Graphic Designer, Interactive De- ting, che è un’infrastruttura di comunicazione
signer e Web Designer) per la definizione estendibile e pensata specificatamente per il
di layout di applicazioni sia Windows che dialogo da .NET verso .NET. Infine per crea-
Web, pensati per ottimizzare lo studio e la re componenti transazionali, scalabili, confi-
produzione di contenuti grafici da utilizza- gurabili decorando le loro definizioni con at-
re in associazione con il codice scritto da- tributi .NET, dobbiamo rivolgerci ai Service-
gli sviluppatori. Sono strumenti che nasco- dComponents per COM+, seppur sviluppati
no con l’obiettivo di consentire ai grafici con codice .NET.

12 VBJ N. 69 - Maggio/Giugno 2006


WinFX

Come si vede ad oggi abbiamo un’offerta di struttura di WCF. I messaggi possono es-
servizi decisamente articolata e spesso non sere pensati in ottica SOA, pensando pri-
ben amalgamata e coesa. Cosa accade nel mo- ma di tutto al XSD, oppure possono esse-
mento in cui dobbiamo sviluppare un servi- re oggetti .NET da serializzare e trasferi-
zio SOAP via HTTP, sicuro con WS-Security re, come accade oggi con .NET Remoting.
e transazionale? Come possiamo scegliere tra Esistono diversi modi di rappresentare i
ASMX, WSE3 e un ServicedComponent? messaggi WCF, in base al tipo di applica-
WCF nasce proprio con l’obiettivo di convo- zione che si vuole realizzare.
gliare in un unico framework tutte le caratte- • Channel: si tratta del canale di trasporto
ristiche e funzionalità orientate allo sviluppo dei messaggi e può essere pensato come
di componenti e applicazioni distribuite, con una pipeline attraverso la quale transitano
l’obiettivo di offrirci un framework unico e i messaggi, applicando estensioni e servizi
completo per lo sviluppo delle infrastrutture sia a livello di messaggio che di protocollo
di comunicazione del domani (Figura 1). di trasporto.
• Endpoint: punto attraverso il quale è possi-
Architettura di WCF bile raggiungere un servizio. Un Endpoint
Dal punto di vista architetturale WCF è pen- è costituito di tre informazioni: Address,
sato per essere estremamente estendibile e Binding e Contract (Figura 2). L’Address
personalizzabile. Alla base della sua architet- rappresenta l’indirizzo al quale è possibi-
tura vi sono i concetti di: le raggiungere il servizio WCF. Il Binding
indica il tipo di protocollo da utilizzare per
• Message: rappresenta il contenitore delle dialogare con quel servizio. Il Contract de-
informazioni da trasferire tramite l’infra- scrive il contratto, cioè l’insieme di opera-

Figura 1 Filosofia alla base del ServiceModel di WCF

N. 69 - Maggio/Giugno 2006 VBJ 13


WinFX

Figura 2 Architettura Service Oriented di WCF

zioni e messaggi, da sottoscrivere con il tocolli di trasporto dei messaggi, che sono det-
servizio per poter dialogare. ti Binding, sono personalizzabili in termini di
• Endpoint Listener: stanno in ascolto di funzionalità e laddove non ci bastino i Binding
messaggi su un particolare Channel che nativi, possiamo crearne di nostri, estendendo
espone un Endpoint. il modello ad oggetti di WCF. I servizi esposti
• ServiceHost: si tratta di chi ospita uno o
possono offrire più o meno funzionalità al con-
più servizi, esponendo un set di Endpoint torno, rispetto al servizio stesso, utilizzando dei
Listener. I ServiceHost possono essere ap- modificatori di comportamento, detti behavior,
plicazioni nostre (self-hosting) o servizi del che sono altrettanto configurabili partendo da
sistema operativo, come per esempio ASP. un insieme di base o definibili in autonomia,
NET con Internet Information Services. creando delle classi .NET ad hoc.
• ChannelFactory: creano canali di comunica-
zione consumer-side, cioè dal lato del client WCF Service Provider
di un servizio, per poter raggiungere un En- Vediamo quindi un esempio di servizio WCF,
dpoint. Da un punto di vista SOA è più cor- creando insieme un Service Provider, cioè
retto parlare di consumer che non di client. un’applicazione che espone un servizio WCF.
Dal momento che un servizio è descritto da
Come si vede l’architettura è assolutamente una terna ABC (Address, Binding, Contract),
orientata ai servizi, in un’ottica squisitamente per prima cosa dobbiamo decidere che tipo
SOA. Tutto ciò di cui è costituita l’architettura di servizio vogliamo realizzare e quindi defi-
di WCF non è solo utilizzabile, ma è anche per- nirne il contratto. Esistono infatti diverse ti-
sonalizzabile e ridefinibile. Ad esempio i pro- pologie di servizi e di contratti:

14 VBJ N. 69 - Maggio/Giugno 2006


WinFX

• ServiceContract: si definisce il contratto in [DataMember]


base al servizio da creare. Si ragiona sul- public Decimal EuroAmount
le operazioni e sugli argomenti (messaggi) {
relativi a queste operazioni. get { return _euroAmount; }
• DataContract: si ragiona sulla base dei set { _euroAmount = value; }
dati da trasferire, all’interno dei messaggi, }
utilizzando un nuovo motore di serializza- [DataMember]
zione (DataContractSerializer) pensato per public DateTime CheckInDateTime
serializzare e deserializzare gli oggetti da {
e verso i messaggi relativi al contratto. In get { return _checkInDateTime; }
questo caso si può anche scegliere di uti- set { _checkInDateTime = value; }
lizzare il serializzatore “vecchio stile” (Xm- }
lSerializer) che viene oggi utilizzato dagli
ASMX, ad esempio per esigenze di com- [DataMember]
patibilità con il passato. public DateTime CheckOutDateTime
• MessageContract: si ragiona sulla base del
{
messaggio da trasferire e si costruisce di get { return _checkOutDateTime; }
conseguenza il contratto del servizio. Nel set { _checkOutDateTime = value; }
codice ci si riferirà al messaggio SOAP in }
termini di Body e Header, associando alle }
varie parti del messaggio le informazioni
presenti nelle entità e oggetti della nostra Il DataContract non è altro che una norma-
infrastruttura di codice. lissima classe, dove i membri che vogliamo
“pubblicare” all’interno del contratto sono de-
Proviamo quindi a definire un contratto con corati con attributi relativi al motore di seria-
approccio DataContract. Dobbiamo innanzi- lizzazione DataContractSerializer. Ad esempio
tutto descrivere le entità da trasferire come per dichiarare che una proprietà deve esse-
messaggi. re serializzata le applichiamo l’attributo Da-
Immaginiamo di voler esporre un classico taMember, mentre per dichiarare che l’intera
servizio di prenotazione camere in hotel. In- classe deve essere serializzabile le applichia-
nanzitutto pensiamo a come si descrive una mo l’attributo DataContract. Questi attribu-
prenotazione: ti si trovano nell’assembly System.Runtime.
Serialization.dll del SDK di WinFX/Windows
C# Vista, nell’omonimo namespace.
[DataContract()] Se scegliamo la strada del DataContract, tut-
public class HotelReservation ti gli oggetti che andremo a serializzare do-
{ vranno essere opportunamente decorati per
private Hotel _hotel; comunicare al motore di serializzazione quali
private Decimal _euroAmount; informazioni vogliamo persistere nel messag-
private DateTime _checkInDateTime; gio. Nell’esempio allegato all’articolo trovano
private DateTime _checkOutDateTime; quindi posto anche la definizione del concet-
to di hotel (classe Hotel) e di conferma della
[DataMember] prenotazione di un hotel (classe HotelReser-
public Hotel Hotel vationConfirmation).
{ Dopo aver descritto le entità, dobbiamo di-
get { return _hotel; } chiarare un’interfaccia (dal punto di vista del
set { _hotel = value; } codice .NET) o una classe, all’interno della
} quale definiremo le operazioni da eseguire,

N. 69 - Maggio/Giugno 2006 VBJ 15


WinFX

che saranno basate sul DataContract prece- result.CheckInDateTime = reservation.Check


dentemente dichiarato. InDateTime;
result.CheckOutDateTime = reservation.Check
C# OutDateTime;
[ServiceContract(Namespace=”http:// result.EuroAmount = reservation.EuroAmount;
schemas.devleap.com/HotelService”)] result.IdConfirmation = 1;
public interface IHotelService result.IdHotel = reservation.Hotel.IdHotel;
{
[OperationContract()] return (result);
HotelReservationConfirmation MakeReservation }
(HotelReservation reservation); }
}
Anche in questo caso possiamo utilizzare
Come si vede anche in questo caso utilizzia- degli appositi attributi di WCF per associa-
mo pesantemente gli attributi .NET per comu- re al servizio un particolare comportamen-
nicare al motore di WCF il fatto che l’interfaccia to (Behavior).
IHotelService descrive il contratto di un servi- Alternativamente possiamo definire questi
zio (ServiceContract) che è riconoscibile in base comportamenti e caratteristiche accessorie
al suo namespace XML. Inoltre dichiariamo che nel file di configurazione dell’applicazione
esiste una operazione (OperationContract) di che implementa il ServiceHost.
nome MakeReservation che riceve in ingresso
il DataContract precedentemente definito (Ho- WCF ServiceHost
telReservation) e restituisce un altro DataCon- Il ServiceHost abbiamo detto essere l’appli-
tract (HotelReservationConfirmation). cazione che pubblica fisicamente un servizio
A questo punto possiamo implementare il WCF, mettendosi in ascolto su uno o più En-
servizio con una classe specifica. dpointListener. Un ServiceHost è una qual-
siasi applicazione .NET che sia in grado di
Il fatto di poter implementare il contratto pubblicare uno o più servizi WCF, attraver-
con una classe significa che a parità di con- so una o più porte di accesso (definite da un
tratto possiamo avere potenzialmente N diver- Binding e un Address).
se sue implementazioni. Già qui si assapora Ciò significa che possiamo esporre uno stes-
quindi la versatilità di uno strumento come so servizio (Contract e implementazione) at-
WCF, che consente di avere definizioni astrat- traverso diversi protocolli (Binding) e conse-
te di servizi (il contratto) e loro implementa- guentemente diversi indirizzi di accesso (Ad-
zioni particolari, in ottica SOA. dress), oppure che possiamo con uno stesso
Ecco il servizio che implementa il con- ServiceHost pubblicare diversi contratti, ov-
tratto: viamente sempre su diversi indirizzi e/o pro-
tocolli.
C# Un’applicazione che si comporti da Servi-
[ServiceBehavior(InstanceContextMode= ceHost deve al minimo istanziare proprio
InstanceContextMode.PerCall)] public class una classe di nome ServiceHost, che può es-
HotelService : IHotelService sere istanziata sulla base di un particolare
{ servizio.
public HotelReservationConfirmation Make
Reservation(HotelReservation reservation) C#
{ using(ServiceHost host = new ServiceHost(typeof
HotelReservationConfirmation result = new (HotelService)))
HotelReservationConfirmation(); {

16 VBJ N. 69 - Maggio/Giugno 2006


WinFX

try sulla sua configurazione, senza dover ricom-


{ pilare nulla o dovendo comunque intervenire
host.Open(); minimamente sul codice .NET. Ecco che allo-
Console.WriteLine(“Host in ascolto...\ ra a parità di contratto e di sua implementa-
nPremere INVIO per terminare”); zione possiamo adattare i protocolli e le carat-
} teristiche dei servizi alle varie situazioni, ac-
catch (CommunicationException ex) cendendo e spegnendo le funzionalità acces-
{ sorie in base all’occorrenza. In questo modo
Console.WriteLine(ex); avremo applicazioni e comunicazioni sicure
} (WS-Security), affidabili (WS-ReliableMessa-
Console.ReadLine(); ging), transazionali (WS-AtomicTransaction),
} ecc. solo grazie a servizi infrastrutturali che
non richiedono variazioni al nostro codice. I
Il ServiceHost può essere configurato da protocolli di trasporto offerti da WCF sono rie-
codice oppure, molto più comodamente, at- pilogati in Figura 3.
traverso il suo file di configurazione (App.
Config). WCF Service Consumer
I servizi pubblicati da un ServiceHost de-
<?xml version=”1.0” encoding=”utf-8”?> vono poi di solito essere “consumati” da un
<configuration> Service Consumer. Nel caso in cui il servizio
<system.serviceModel> debba essere interoperabile con il resto del
<services> mondo e il consumer sia ad esempio un’ap-
<service name=”DevLeap.WCF.Contract plicazione Java, potremo esporre il servizio
BasedService.HotelService”> utilizzando un Binding appropriato come
<endpoint Address=”http:// basicHttpBinding, che supporta WS-I Basic
localhost:9001/HotelService” Profile 1.1 [1] e garantisce quindi la com-
Binding=”wsHttpBinding” Contract=”DevLeap.WCF. patibilità con le altre piattaforme software.
ContractBasedService.IHotelService” /> Nel nostro caso abbiamo scelto di utilizzare
</service> il protocollo wsHttpBinding, che è in grado
</services> di dialogare con chi supporta le specifiche
WS-Security e WS-* in generale e supporta
</system.serviceModel> transazioni distribuite. Volendo consumare il
</configuration> servizio con un’applicazione WinFX dobbia-
mo innanzitutto creare un proxy, lato consu-
All’interno del file di configurazione trova- mer, in grado di raggiungere la terna ABC
no definizione il nome del servizio, che cor- del servizio.
risponde alla sua implementazione particola- Per farlo possiamo utilizzare il tool del SDK
re, il Binding e l’Address nonché il contratto. di WinFX chiamato SVCUTIL.EXE. Questo
In sostanza definiamo la terna ABC e dichia- tool a riga di comando svolge un’attività equi-
riamo per quale particolare implementazio- valente alla “Add Web Reference” di Visual
ne del contratto debba essere utilizzata. Po- Studio 2005, salvo il fatto che crea una clas-
tremmo anche definire, sempre nel file .con- se proxy basata su WCF anziché sui web ser-
fig, il comportamento del servizio in termini vice ASMX.
di sicurezza, transazionalità, instancing, re- Dobbiamo invocare il tool dandogli in input
liability, ecc. i metadati (WSDL, XSD, Policy) del servizio.
Questo ci porta a considerare che un servizio, Se non abbiamo già i metadati possiamo far-
a parità di implementazione, può assumere di- celi creare da SVCUTIL stesso, dandogli in
versi comportamenti, semplicemente agendo input prima l’assembly del servizio

N. 69 - Maggio/Giugno 2006 VBJ 17


WinFX

Figura 3 Binding supportati nativamente da WCF

Command Prompt A questo punto possiamo accedere al servi-


D:\>SVCUTIL.EXE DevLeap.WCF.ContractBased zio, attraverso il suo contratto, o creando di-
Service.dll rettamente un’istanza della classe proxy au-
togenerata:
Quindi i metadati ottenuti da questa prima
esecuzione C#
HotelServiceProxy proxy = new HotelServiceProxy();
Command Prompt
HotelReservation reservation = new Hotel
D:\>SVCUTIL.EXE DevLeap.WCF.ContractBasedSer-
Reservation();
vice.xsd schemas.devleap.com.HotelService.wsdl
schemas.devleap.com.HotelService1.xsd schemas.
reservation.CheckInDateTime = DateTime.Now.
microsoft.com.2003.10.Serialization.xsd
AddDays(2);
reservation.CheckOutDateTime = DateTime.Now.
Come si vede SVCUTIL genera una se-
rie di file (WSDL e XSD) che descrivono il AddDays(3);

servizio e i suoi messaggi, quindi leggen- reservation.EuroAmount = 100;

doli genera un file di codice .NET (C# di reservation.Hotel = new Hotel();


default) ed eventualmente un file di con- reservation.Hotel.IdHotel = 1;
figurazione (App.Config) da utilizzare sul reservation.Hotel.Level = HotelLevel.FourStars;
consumer. reservation.Hotel.Name = “Hotel WCF”;

18 VBJ N. 69 - Maggio/Giugno 2006


WinFX

HotelReservationConfirmation confirmation = <wsHttpBinding>


proxy.MakeReservation(reservation); <Binding name=”customReliable”>
<reliableSession enabled=”true”
Oppure utilizzando direttamente la classe ordered=”true” />
ChannelFactory, per creare un canale consu- </Binding>
mer verso il contratto </wsHttpBinding>
</Bindings>
C#
ChannelFactory<IHotelService> proxy = new Channel In questo modo dichiariamo che il canale
Factory<IHotelService>(); di comunicazione deve essere reliable e che
i messaggi devono essere consegnati nel-
In questo secondo caso potremmo avere con- l’ordine esatto in cui vengono spediti. Se
sumer-side solo la definizione del contratto e poi volessimo utilizzare un protocollo diver-
dei suoi messaggi, senza dover generare l’in- so da HTTP, ad esempio MSMQ, potremmo
tera classe proxy. dichiarare:
Anche il consumer avrà bisogno, dal suo
lato, di avere un file di configurazione (App. <services>
Config) corrispondente in termini di Address, <service name=”DevLeap.WCF.ContractBased
Binding ed eventuali behavior a quanto defi- Service.HotelService”>
nito dal lato del service provider. <endpoint Address=”net.msmq://paoloxp/pri-
vate/HotelServiceQueue” Binding=”netMsmqBinding”
<?xml version=”1.0” encoding=”utf-8”?> BindingConfiguration=”msmqHotelService”
<configuration> Contract=”DevLeap.WCF.ContractBasedService.
<system.serviceModel> IHotelService” />
<client> </service>
<endpoint Address=”http://local- </services>
host:9001/HotelService” Binding=”wsHttpBinding”
Contract=”IHotelService” /> Come si vede, a parità di contratto e di im-
</client> plementazione, cambiamo soltanto il tipo di
</system.serviceModel> Binding e il relativo Address.
</configuration>
Conclusioni
Dal lato del consumer abbiamo definito solo WinFX ad oggi è in versione beta, ma è sca-
il contratto, il Binding e l’Address in quanto ricabile dal sito MSDN di Microsoft [2]. Inol-
l’implementazione non è necessaria e non è tre WCF e WF sono in versione GoLive, cioè
presente. utilizzabili in applicazioni reali, oltre che per
ricerca e sviluppo interno.
Punti chiave Consiglio quindi di scaricare l’ultima build
Un aspetto chiave dell’architettura e della di WinFX e iniziare a valutare questo nuovo
filosofia di WCF è il fatto che nulla ci vieta a e interessante framework, che in parte rivo-
questo punto di modificare tanto sul provider, luzionerà il modo di scrivere le nostre appli-
quanto sul consumer il Binding, piuttosto che cazioni.
il Behavior. Ad esempio potremmo abilitare
la Reliability della comunicazione semplice- Riferimenti
mente aggiungendo al .config del provider e [1] http://www.ws-i.org/
del consumer qualche tag XML: [2] http://msdn.microsoft.com/winfx/
[3] http://windowscommunication.net/
<Bindings> [4] http://www.devleap.com/winfx/

N. 69 - Maggio/Giugno 2006 VBJ 19


VB6

Accesso al filesystem
da Visual Basic 6
con classi .NET
Come accedere alle funzionalità del Microsoft .NET Framework ine-
renti al filesystem dalle applicazioni Visual Basic 6 esistenti, e ottenere
l’estensione di un file, la parte directory del percorso o il nome del file e
come scatenare eventi quando cambia il contenuto di una directory

di Scott Swigart - Swigart Consulting LLC. Filesystem

L’
accesso al filesystem è un prerequisito
comune di una applicazione, e in que-
sto articolo mostrerò come si può acce-
dere ad alcune delle migliori funzionalità del .NET
Framework inerenti al filesystem dalle applicazio-
ni Visual Basic 6.
In primo luogo, esiste la classe Path. Questa classe
semplifica notevolmente l’interazione con e l’estra-
zione di parti delle stringhe dei percorsi del filesy-
stem. Con una sola riga di codice, si può ottenere
l’estensione di un file, o la parte directory di un
percorso, o ricavare la parte del nome del file da
un percorso. Si può anche modificare l’estensione
di un file, o determinare se un percorso è relativo
o assoluto.
Figura 1 La finestra di dialogo Folder Browser
Inoltre, esiste la classe FolderBrowserDialog, che
facilita la visualizzazione di una finestra di dialogo

© 2006 Microsoft Corporation. All rights reserved che permette all’utente di sele-
zionare un percorso a una car-
Scott Swigart fornisce consulenza alle aziende su come uti- tella (Figura 1).
lizzare al meglio l’attuale tecnologia e prepararsi al domani.
La visualizzazione di questa fi-
A tal riguardo, Scott è un orgoglioso collaboratore del sito VB
Fusion, dove offre informazioni e strategie di reale utilizzo per nestra di dialogo di sistema da
gli sviluppatori VB che vogliono realizzare il maggior numero Visual Basic 6 richiede una certa
di funzionalità con il minimo sforzo. Scott è anche un Microsoft quantità di invocazioni alle API
MVP, ed è coautore di numerosi libri e articoli, ed è contattabile
all’indirizzo email scott@swigartconsulting.com.
Win32. Tuttavia, utilizzando la
libreria IOLib allegata a questo

N. 69 - Maggio/Giugno 2006 VBJ 21


VB6

Figura 2 Invocazione del .NET Framework con classi wrapper

articolo (scritta in Visual Basic 2005), si può può utilizzare IOLib dalle proprie applicazio-
facilmente visualizzare questa finestra di dia- ni Visual Basic 6. Se si è interessati a come
logo da una applicazione Visual Basic 6. è stato costruito IOLib, l’articolo si conclu-
Infine, l’articolo esamina la classe FileSy- de con una analisi sulla realizzazione di pro-
stemWatcher. Questa classe può scatenare prie classi wrapper.
eventi ogni volta che cambia il contenuto di
una directory. Pertanto questa classe è l’idea- Utilizzo della classe Path
le se si ha un’applicazione che deve processa- da Visual Basic 6
re nuovi file man mano che vengono creati o Talvolta, un’applicazione deve manipolare
modificati. E di nuovo, può essere utilizzata una stringa di percorso di un file. Ad esem-
facilmente da Visual Basic 6. pio, si può avere un percorso completo a un
file, ma si è interessati a ricavare la sola par-
I fondamenti: invocare .NET da Visual te directory del percorso. Altre volte, si può
Basic 6 voler ottenere solo il nome del file, senza le
In genere, non si possono invocare diretta- informazioni sulla directory. In ulteriori casi,
mente da Visual Basic 6 classi del .NET Fra- si può voler esaminare l’estensione del file in
mework poiché queste non vengono esposte modo da poter intraprendere azioni differenti
come oggetti COM. Tuttavia, si può utilizza- per differenti tipi di file. Si può anche voler
re Visual Basic 2005 per creare dei wrapper modificare l’estensione di un file se lo si sta
COM per le parti del .NET Framework che si caricando in un formato e lo si vuole salvare
intende utilizzare. Il proprio codice Visual Ba- con un formato differente.
sic 6 invoca il wrapper COM, e questo invoca La classe Path è concepita per rendere que-
il.NET Framework (Figura 2). sti tipi di operazioni molto semplici. La clas-
Si tratta dell’approccio utilizzato in que- se IOLib allegata a questo articolo avvolge la
sto articolo. Il codice d’esempio dell’articolo classe Path .NET in modo da poterla invoca-
comprende il progetto Visual Basic 2005 de- re da Visual Basic 6 o da altri ambienti basa-
nominato IOLib che funge da wrapper delle ti su COM. Attraverso questo wrapper COM,
classi Path, FolderBrowserDialog e FileSy- si può accedere alle funzionalità elencate in
stemWatcher del .NET Framework. Nell’ar- Tabella 1.
ticolo verrà inizialmente mostrato come si L’analisi che segue illustra l’utilizzo della

22 VBJ N. 69 - Maggio/Giugno 2006


VB6

Tabella 1 Funzionalità del wrapper COM

Proprietà o metodo Descrizione

ChangeExtension Modifica l’estensione di una stringa di percorso

Combine Unisce due stringhe di percorso

GetDirectoryName Restituisce le informazioni directory della stringa di percorso specificata

GetExtension Restituisce l’estensione della stringa di percorso specificata

GetFileName Restituisce nome e estensione del file della stringa di percorso specificata

GetFullPath Restituisce il percorso assoluto della stringa di percorso specificata

GetPathRoot Restituisce le informazioni della directory radice del percorso specificato

Restituisce un file temporaneo a lunghezza zero di nome univoco creato su disco e restituisce il
GetTempFileName
percorso completo a questo file

GetTempPath Restituisce il percorso della cartella temporanea corrente di sistema

HasExtension Determina se un percorso comprende l’estensione di un nome di file

Restituisce un valore che indica se la stringa di percorso specificata contiene informazioni su un


IsPathRooted
percorso assoluto o relativo

Fornisce un array di caratteri, dipendente dalla piattaforma, che non può essere specificato negli
InvalidPathChars
argomenti della stringa di percorso passati ai membri della classe Path

classe Path da Visual Basic 6. Prima di com- 6. Premere OK.


pletare questa analisi, si deve installare Vi- 7. Selezionare l’opzione di menu Project |
sual Studio 2005, Visual Basic Express. Visual References.
Basic Express è una versione relativamente 8. Selezionare IOLib.
ridotta ed è disponibile gratuitamente all’in- 9. Premere OK.
dirizzo http://msdn.microsoft.com/vstudio/ex- Così facendo si sono referenziate le DLL
press/vb/default.aspx, e si può installare su .NET necessarie a visualizzare la finestra
macchine già dotate di Visual Studio 6.0, Vi- di dialogo per esaminare le cartelle da Vi-
sual Studio .NET, Visual Studio 2003 o Visual sual Basic 6. È giunto il momento di rea-
Studio 2005, senza alcun problema. lizzare l’interfaccia utente.
10. Nella Toolbox, effettuare un doppio clic
1. Se non si è già eseguita l’installazione del sul controllo CommonDialog per aggiun-
codice d’esempio, nella cartella del codi- gerlo al form.
ce d’esempio di questo articolo, aprire la 11. Aggiungere al form un controllo TextBox,
sottocartella Code, e avviare install.bat. e ridimensionarlo in modo che occupi gran
Questa azione registra le DLL del .NET Fra- parte del form.
mework, e il wrapper IOLib in modo che 12. Nella finestra Properties del controllo
possa essere utilizzato da Visual Basic 6.0 Text1 impostare le seguenti proprietà:
2. Avviare Visual Basic 6.0. • Multiline = True
3. Dalla finestra di dialogo New Project, sele- • Text = (stringa vuota)
zionare Standard EXE, e premere Open.
4. Clic destro sulla Toolbox e selezionare Questo controllo textbox visualizzerà le in-
Components... formazioni su un file selezionato utilizzando
5. Nella finestra di dialogo Components, se- la classe Path.
lezionare Microsoft Common Dialog Con- 13. Clic destro sul form e selezionare View Code.
trol 6.0. 14. Inserire il seguente codice:

N. 69 - Maggio/Giugno 2006 VBJ 23


VB6

Private Sub Form_Load() Come si può vedere, quando si seleziona


un file, questa applicazione mostra diver-
Dim path As New IOLib.PathWrapper se informazioni riguardo al percorso del file
With CommonDialog1 (Figura 3).
Con una sola riga di codice, l’applicazione
.ShowOpen può separare il nome del file dal percorso
della directory. L’applicazione può anche de-
If .FileName <> “” Then terminare se il file ha un’estensione, e qual è
Text1 = “Directory: “ & path.GetDirectory l’estensione. Infine, l’applicazione può indica-
Name(.FileName) & _ re la cartella radice del percorso, e se il per-
vbCrLf corso è relativo o assoluto. Con Visual Basic
Text1 = Text1 & “Ha estensione: “ & _ 6, è spesso necessario scrivere direttamente
path.HasExtension(.FileName) & vbCrLf la logica di suddivisione della stringa per ot-
Text1 = Text1 & “Estensione: “ & _ tenere questi blocchi di informazione, ed è
path.GetExtension(.FileName) & vbCrLf quindi facile introdurre dei bug se l’utente
Text1 = Text1 & “Nome file: “ & _ fornisce dei percorsi UNC, o altri formati di
path.GetFileName(.FileName) & vbCrLf percorso che la propria applicazione può non
Text1 = Text1 & “Radice: “ & _ aver previsto. Non solo il ricorso alla classe
path.GetPathRoot(.FileName) & vbCrLf Path è più agevole della scrittura di una pro-
Text1 = Text1 & “Assoluto o Relativo: “ & _ pria logica, ma è anche stata testata con un
IIf(path.IsPathRooted(.FileName), gran numero di tipologie di percorsi.
“Assoluto”, “Relativo”)
End If Utilizzo di FolderBrowserDialog da
Visual Basic 6
End With La finestra di dialogo per esaminare le car-
telle è molto utile quando è necessario che
End Sub l’utente selezioni una cartella (piuttosto che
uno specifico file). Il sistema operativo com-
15. Premere F5 per avviare l’applicazione. prende una finestra di dialogo nativa per esa-
minare le cartelle, ma
Visual Basic 6 non for-
nisce l’accesso a questa
finestra di dialogo. Se
si vuole visualizzare il
browser delle cartelle da
Visual Basic 6, è neces-
sario invocare SHBrow-
seForFolder e altre fun-
zioni API Win32. Tutta-
via, il .NET Framework
contiene una classe Fol-
derBrowserDialog, e il
codice di IOLib allega-
to a questo articolo av-
volge la classe Folder-
Figura 3 Utilizzo della classe Path da Visual Basic 6
BrowserDialog in modo
che possa essere facil-
mente utilizzata da Vi-

24 VBJ N. 69 - Maggio/Giugno 2006


VB6

Tabella 2 Funzionalità FolderBrowserDialogWrapper

Proprietà o metodo Descrizione

Restituisce o imposta il testo descrittivo visualizzato sopra il controllo treeview nella


Description
finestra di dialogo

Reset Reimposta le proprietà ai rispettivi valori di default

RootFolder Restituisce o imposta la cartella radice da dove inizia l’esplorazione del filesystem

SelectedPath Restituisce o imposta il percorso selezionato dall’utente

ShowDialog Visualizza la finestra di dialogo per esaminare le cartelle

Restituisce o imposta un valore che indica se il pulsante New Folder appare nella
ShowNewFolderButton
finestra di dialogo per esaminare le cartelle

sual Basic 6. La classe IOLib FolderBrowser- fb.ShowNewFolderButton = True


DialogWrapper espone le funzionalità elen- fb.RootFolder = SpecialFolderWrapper_ProgramFiles
cate nella Tabella 2.
I passi che seguono illustrano l’utilizzo della If fb.ShowDialog = DialogResult_OK Then
classe FolderBrowserDialog da Visual Basic 6. MsgBox fb.SelectedPath
End If
1. Se non si è già eseguita l’installazione del
codice d’esempio, eseguire install.bat come Ciò crea un’istanza della classe della finestra di
si è descritto al punto 1 precedente per dialogo. Questo wrapper viene poi utilizzato per
registrare le DLL del .NET Framework, e configurare le proprietà, tra cui il testo descrit-
la classe wrapper IOLib in modo che possa tivo e la cartella di partenza. Il dialogo per esa-
essere utilizzata da Visual Basic 6.0. minare le cartelle è anche configurato per per-
2. Avviare Visual Basic 6.0. mettere all’utente di creare una nuova cartella
3. Nel dialogo New Project, selezionare Stan- per mezzo della finestra di dialogo. Infine, vie-
dard EXE, e premere Open. ne mostrata la finestra di dialogo, e se l’utente
4. Selezionare l’opzione di menu Project | preme il pulsante OK, viene processato il per-
References. corso selezionato nella finestra di dialogo.
5. Selezionare IOLib, e System.Windows.For- 9. Premere F5 per avviare l’applicazione. Ap-
ms.DLL. parirà la finestra di dialogo mostrata in Fi-
6. Premere OK. gura 4.
Così facendo si sono referenziate le DLL Quando viene selezionata una cartella, si
.NET necessarie a visualizzare la finestra vedrà che il percorso della cartella appare
di dialogo per esaminare le cartelle da Vi- nella messagebox (Figura 5).
sual Basic 6. È giunto il momento di scri-
vere del codice. Si può osservare che la visualizzazione del-
7. Effettuare un doppio clic su Form1 nel desi- la finestra di dialogo per esaminare le cartel-
gner per far sì che Visual Basic generi la subrou- le da Visual Basic 6 utilizzando il .NET Fra-
tine Form_Load e apra l’editor del codice. mework è molto più facile che utilizzando le
8. All’interno di Form_Load, inserire il se- invocazioni alla API Win32.
guente codice:
Utilizzo di FileSystemWatcher
Dim fb As New IOLib.FolderBrowserDialogWrapper Ho lasciato per ultima la parte più succosa
dell’articolo. Il Microsoft .NET Framework
fb.Description = “Selezionare una cartella” comprende una classe denominata FileSy-

N. 69 - Maggio/Giugno 2006 VBJ 25


VB6

Figura 5 Visualizzazione della cartella selezio-


nata dall’utente

8. Aggiungere al form un controllo Comman-


dButton e un controllo TextBox.
Figura 4 Visualizzazione della finestra di dialogo
9. Per il CommandButton, impostare la pro-
da Visual Basic 6 prietà text a Start Watching.
10. Per il TextBox:
• Impostare con una stringa vuota la
stemWatcher, che genera un evento ogni vol- proprietà Text.
ta che i file di una cartella vengono creati, • Impostare la proprietà MultiLine a
eliminati, modificati o rinominati. Normal- True.
mente, non si può utilizzare direttamente Fi- 11. Effettuare un doppio clic sul Form per
leSystemWatcher da Visual Basic 6, ma IOLib far sì che Visual Basic generi l’handler
(fornito con questo articolo) avvolge FileSy- d’evento Form_Load, e apra l’editor del
stemWatcher, semplificando l’utilizzo dagli codice.
ambienti COM. 12. Nella sezione General Declarations (sopra
La seguente analisi mostra come utilizzare Form_Load), immettere il seguente codice:
FileSystemWatcher per rilevare le modifiche
in una directory. Private WithEvents fsw As IOLib.FileSystemWatcher
Wrapper
1. Se non si è già eseguita l’installazione del
codice d’esempio, eseguire install.bat come 13. Nell’evento Form_Load, inserire il seguen-
si è già detto. te codice:
2. Creare una nuova cartella su disco rigido,
denominandola C:\WatchedFolder. Que- Set fsw = New IOLib.FileSystemWatcherWrapper
sta cartella verrà monitorata da FileSy-
stemWatcher per rilevare le eventuali mo- A questo punto, si è creata un’istanza della
difiche. classe che verrà utilizzata per monitorare la
3. Avviare Visual Basic 6.0. directory C:\WatchedFolder per qualsiasi mo-
4. Nella finestra di dialogo New Project, sele- difica.
zionare Standard EXE e premere Open. 14. Dall’elenco a discesa Object, selezionare
5. Selezionare l’opzione di menu Project | Command1 (Figura 6).
References. Ciò genererà l’evento click per il controllo
6. Selezionare IOLib. CommandButton.
7. Premere OK. 15. Nell’evento Command1_Click, immettere
Così facendo si sono referenziate le DLL il seguente codice:
.NET necessarie per utilizzare la classe Fi-
leSystemWatcher da Visual Basic 6. fsw.InitWatcher (“C:\WatchedFolder”)

26 VBJ N. 69 - Maggio/Giugno 2006


VB6

Figura 6 Il processo di traduzione

fsw.IncludeSubDirectories = True 18. Nell’elenco a discesa Procedure, seleziona-


fsw.EnableRaisingEvents = True re Created (Figura 7).
Con ciò verrà generato l’handler d’even-
Questo codice indica a FileSystemWatcher to fsw_Created. Questo evento si scatena
quale cartella dovrà monitorare. Inoltre, ogni qualvolta un nuovo file appare nella
indica che devono essere monitorate le directory C:\WatchedFolder.
sottodirectory di questa cartella. Infine, 19. Nell’handler d’evento fsw_Created, inseri-
indica a FileSystemWatcher di iniziare a re il seguente codice:
generare eventi non appena avviene una
modifica. Text1 = Text1 & “Creato: “ & e.FullPath & vbCrLf
L’ultimo compito che resta è collegare gli
handler d’evento per processare le modifi- 20. Ripetere i passi 18 e 19 per creare gli hand-
che. ler d’evento degli eventi Deleted e Renamed.
16. Dall’elenco a discesa Object, selezionare Il codice finale deve apparire come segue:
fsw.
Ciò genera l’handler d’evento fsw_Chan- Private WithEvents fsw As IOLib.FileSystem
ged, che verrà scatenato ogni volta che vie- Watcher Wrapper
ne modificato un file della directory C:\Wa-
tchedFolder. Private Sub Command1_Click()
17. Nell’handler d’evento fsw_Changed, inse- fsw.InitWatcher (“C:\WatchedFolder”)
rire il seguente codice: fsw.IncludeSubDirectories = True
fsw.EnableRaisingEvents = True
Text1 = Text1 & “Modificato: “ & e.FullPath & vbCrLf End Sub

N. 69 - Maggio/Giugno 2006 VBJ 27


VB6

Figura 7 Selezione dell’evento Created dall'elenco a discesa delle procedure

Private Sub Form_Load() Text1 = Text1 & “Rinominato: “ & e.FullPath


Set fsw = New IOLib.FileSystemWatcherWrapper & vbCrLf
End Sub End Sub

Private Sub fsw_Changed(ByVal e As IOLib.File 21. Premere F5 per eseguire l’applicazione.


SystemEventArgsWrapper) 22. Cliccare Start Watching.
Text1 = Text1 & “Modificato: “ & e.FullPath 23. Aprire Windows Explorer e navigare fino
& vbCrLf alla directory C:\WatchedFolder.
End Sub 24. Selezionare il comando di menu File | New
Private Sub fsw_Created(ByVal e As IOLib.File | Text document.
SystemEventArgsWrapper) Ciò crea un nuovo file nella cartella, e scate-
Text1 = Text1 & “Creato: “ & e.FullPath & vbCrLf nerà un evento nella propria applicazione.
End Sub 25. Rinominare il nuovo file test.txt.
26. Eliminare test.txt.
Private Sub fsw_Deleted(ByVal e As IOLib.File 27. Tornare all’applicazione. Apparirà quanto
SystemEventArgsWrapper) mostrato nella Figura 8.
Text1 = Text1 & “Eliminato: “ & e.FullPath
& vbCrLf Si può osservare che l’applicazione è sta-
End Sub ta in grado di monitorare le modifiche nella
directory, e che queste vengono visualizzate
Private Sub fsw_Renamed(ByVal e As IOLib.File nel controllo textbox. Spesso ciò viene uti-
SystemEventArgsWrapper) lizzato per l’elaborazione batch di file man

28 VBJ N. 69 - Maggio/Giugno 2006


VB6

.NET Framework. Quan-


do l’utente invoca Show-
Dialog del wrapper, vie-
ne invocato ShowDia-
log della classe Folder-
BrowserDialog. Quando
l’utente imposta la pro-
prietà Description del
wrapper, viene imposta-
ta la proprietà Descrip-
tion di FolderBrowser-
Dialog. Il più delle vol-
te, non vi è nulla di trop-
po complicato sulle clas-
si wrapper. Il loro prin-
cipale scopo è esporre
un’interfaccia COM, e
delegare alla classe de-
Figura 8 Output dell’applicazione Visual Basic 6 utilizzando FileSystemWatcher
siderata del .NET Fra-
mework.
La seguente analisi vi
mano che vengono caricati su una macchi- guiderà, passo per passo, alla creazione di un
na, esportati da un mainframe, o vengono wrapper minimale che avvolge FolderBrow-
altrimenti posizionati in una cartella di “eli- serDialog, per permettervi di comprendere
minazione”. ulteriormente come avviene la costruzione
di un wrapper.
Esame della costruzione di IOLib
Nel codice allegato è presente una cartel- Costruzione di un wrapper
la IOLib. Un doppio clic sul file IOLib.sln in per FolderBrowserDialog
questa cartella aprirà la soluzione in Visual Il primo compito sarà creare la classe wrap-
Studio 2005 (o in Visual Basic Express). Al- per. Una volta creata, la si utilizzerà da Vi-
l’apertura della soluzione, si sarà in grado di sual Basic 6.
vedere le varie classi wrapper elencate nel
Solution Explorer (Figura 9). Un doppio clic 1. (Solo Visual Basic Express) Copiare il file
su una di queste classi wrapper aprirà il file ComClass.zip presente nel codice allegato
nell’editore di codice. Se, ad esempio, si ese- nella cartella C:\Documenti e Impostazioni\
gue un doppio clic sul file FolderBrowserDia- [Nome Utente]\My Documents\Visual Stu-
logWrapper.vb, si vedrà il codice riportato nel dio 2005\Templates\ItemTemplates\Visual
Listato 1. Basic
Ci sono due cose importanti da notare in 2. Avviare Microsoft Visual Basic 2005 Ex-
questa classe. Per prima cosa, si può vedere press Edition, o Microsoft Visual Studio
che la classe utilizza l’attributo ComClass, 2005.
e contiene diversi GUID. Questi assicurano 3. Selezionare il comando di menu File | New
che la classe può essere opportunamente re- Project.
gistrata come oggetto COM, ed essere uti- La classe wrapper sarà un progetto class
lizzabile da Visual Basic 6. Inoltre, la clas- library, che verrà quindi compilato in una
se fornisce solo dei semplici wrapper alla DLL, in modo analogo a quanto accadreb-
sottostante classe FolderBrowserDialog del be per un componente COM.

N. 69 - Maggio/Giugno 2006 VBJ 29


VB6

4. Nella finestra di dialogo New Project: • Per Templates, selezionare COM Class.
• (Solo VS 2005) Per Project Types, selezio- • Per Name inserire FolderBrowserDialog
nare Visual Basic Projects. Wrapper.
• Per Templates, selezionare Class Library. • Cliccare OK.
• Per Name, inserire FBWrapper. Ciò ha creato l’inizio della classe wrapper.
• Cliccare OK. Ora è necessario scrivere il codice che av-
5. In Solution Explorer, effettuare un clic de- volgerà la classe FolderBrowserDialog.
stro su Class1.vb e selezionare Delete. 9. Selezionare il comando di menu Project |
6. Cliccare OK. Add Reference.
Class1 non è necessaria poiché è una 10. Nella finestra di dialogo Add Reference:
semplice classe .NET, ma non è una clas- • Cliccare System.Windows.Forms.dll.
se COM. Per il wrapper, dobbiamo creare • Cliccare Select.
una classe COM in modo che possa esse- • Cliccare OK.
re utilizzata come oggetto COM da Visual 11. Prima del costruttore Public Sub New, in-
Basic 6. serire la seguente riga di codice:
7. Selezionare il comando di menu Project |
Add New Item. Private fb As New System.Windows.Forms.Folder
8. Nella finestra di dialogo Add New Item: BrowserDialog

Figura 9 Classi wrapper elencate nel Solution Explorer

30 VBJ N. 69 - Maggio/Giugno 2006


VB6

Listato 1 Il codice di FolderBrowserDialogWrapper.vb

Imports System.Windows.Forms
<ComClass(FolderBrowserDialogWrapper.ClassId, FolderBrowserDialogWrapper.InterfaceId, Folder-
BrowserDialogWrapper.EventsId)> _
Public Class FolderBrowserDialogWrapper

#Region “COM GUIDs”


Public Const ClassId As String = “705DDB3F-3A03-4C97-ACE4-9D6F4A50F0AC”
Public Const InterfaceId As String = “CB311CDB-B62A-444E-B415-A253EB579541”
Public Const EventsId As String = “E6B1B7BF-F65B-4A56-9534-5C39332332FB”
#End Region

Private _folderBrowser As FolderBrowserDialog

Public Sub New()


MyBase.New()
_folderBrowser = New FolderBrowserDialog
End Sub

Public Property Description() As String

Get
Return _folderBrowser.Description
End Get

Set(ByVal Value As String)


_folderBrowser.Description = Value
End Set

End Property

Public Sub Reset()


_folderBrowser.Reset()
End Sub
Public Property RootFolder() As SpecialFolderWrapper

Get
Return _folderBrowser.RootFolder
End Get

Set(ByVal Value As SpecialFolderWrapper)


_folderBrowser.RootFolder = Value
End Set

End Property

Public Property SelectedPath() As String

Get
Return _folderBrowser.SelectedPath
End Get

Set(ByVal Value As String)


_folderBrowser.SelectedPath = Value
End Set

End Property

Public Function ShowDialog() As DialogResult


Return _folderBrowser.ShowDialog
End Function

Public Property ShowNewFolderButton() As Boolean


Get
Return _folderBrowser.ShowNewFolderButton
End Get

Set(ByVal Value As Boolean)


_folderBrowser.ShowNewFolderButton = Value
End Set

End Property

End Class

N. 69 - Maggio/Giugno 2006 VBJ 31


VB6

Ciò crea un’istanza del FolderBrowserDia- dler d’evento Form_Load, e apra l’editor di
log che si andrà ad avvolgere. codice.
12. Dopo Public Sub New, ma prima di End 20. Nell’evento Form_Load, inserire il seguen-
Class, inserire il seguente codice: te codice:

Public Function ShowDialog() As System.Windows. Dim fb As New FBWrapper.FolderBrowserDialogWrapper


Forms.DialogResult fb.ShowDialog
Return fb.ShowDialog() MsgBox fb.SelectedPath
End Function
Ciò crea un’istanza della classe wrapper, e
Quando viene invocata la funzione Show- visualizza la finestra di dialogo per naviga-
Dialog del proprio wrapper, questa passe- re tra le cartelle. Quando l’utente selezio-
rà l’invocazione alla sottostante classe Fol- na una cartella, questa viene visualizzata
derBrowserDialog. in una messagebox.
13. Inserire il seguente codice per creare una 21. Premere F5 per eseguire l’applicazione e
proprietà che permetterà alla propria ap- visualizzare la finestra di dialogo.
plicazione Visual Basic 6 di determinare
quale cartella è stata selezionata. Siete liberi di esaminare le altre classi
wrapper in IOLib, e si vedrà che sono imple-
Public Property SelectedPath() As String mentate esattamente in questo modo. Forni-
scono semplicemente un’interfaccia COM, e
Get passano le invocazioni alle sottostanti classi
Return fb.SelectedPath del .NET Framework.
End Get
Conclusioni
Set(ByVal Value As String) In questo articolo, si è visto che il .NET
fb.SelectedPath = Value Framework espone diverse classi molto uti-
End Set li per lavorare con il filesystem.
La classe Path rende agevole lavorare con
End Property le stringhe dei percorsi dei file ed estrar-
re blocchi specifici di informazioni, tra cui
14. Selezionare il comando di menu Build | il nome della directory, il nome del file, e
Build FBWrapper. l’estensione del file.
A questo punto, il wrapper è completo e La classe FolderBrowserDialog fornisce un
può essere utilizzato da Visual Basic 6. facile accesso alla finestra di dialogo di si-
15. Avviare Visual Basic 6. stema che permette all’utente di seleziona-
16. Nella finestra di dialogo New Project, se- re una cartella.
lezionare Standard Exe, e cliccare Open. Infine, la classe FileSystemWatcher ren-
17. Selezionare il comando di menu Project | de agevole monitorare le cartelle e rilevare
References. la creazione di nuovi file o le eventuali mo-
18. Nella finestra di dialogo References, con- difiche.
trassegnare FBWrapper e cliccare OK. Questo articolo comprende anche un com-
Si può vedere che la propria classe wrap- ponente IOLib che funge da wrapper di
per appare in Visual Basic 6 analogamen- queste classi .NET, rendendole utilizzabili
te a qualsiasi altro oggetto COM che basta da Visual Basic 6 o da altri ambienti COM,
referenziare e utilizzare. come Visual Basic for Applications (VBA),
19. Effettuare un doppio clic sul form per far ASP o Visual Basic Scripting Edition (VB-
sì che l’ambiente di sviluppo generi l’han- Script).

32 VBJ N. 69 - Maggio/Giugno 2006


ENTERPRISE

Interoperabilità
COM e .NET Prima puntata
Comprendere e confrontare i modelli di eventi in .NET ed
in COM non solo può aiutarci a specializzare la nostra
conoscenza del framework .NET stesso ma può essere utile
per un miglior riutilizzo event-driven, in applicazioni
.NET, di software binario COM già scritto

COMNET
di Maurizio Mammuccini

I
n questo articolo approfondiamo questioni zare, al meglio, un patrimo-
di interoperabilità .NET e COM concentran- nio software di componenti
doci sui rispettivi modelli di eventi. L’in- binari già scritti
teroperabilità delle architetture d’eventi COM,
deve essere conosciuta da ogni progettista sof- Entrambi i punti elencati, a
tware .NET, anche principiante, il quale intenda mio avviso, richiedono una trat-
sfruttare al meglio le enormi potenzialità insite tazione poiché, eccettuate rare
nell’infrastruttura .NET di Microsoft ed il me- eccezioni nella letteratura di
glio di COM. settore, la loro elaborazione ap-
L’articolo è stato pensato e realizzato con un du- profondita in libri od articoli
plice scopo: è sempre stata abbastanza li-
mitata.
• fornire una breve descrizione non del tutto esau- Ai tempi dei libri su COM/
stiva dell’architettura ad eventi di COM e svol- DCOM, un argomento come
gere delle considerazioni di confronto con il mo- la notifica di un messaggio da
dello ad eventi di .NET Framework un oggetto COM ad un relati-
• fornire utili osservazioni che possano aiutare tut- vo client è stato trattato poco
ti quei progettisti software che in tempi recenti in profondità e molti progettisti
sono migrati (o che stanno migrando) da COM e programmatori si sono spes-
a .NET e che si pongono il problema di riutiliz- so affidati agli esempi tratti da
MSDN o altri siti di sviluppo del
software.
In questo articolo, pur tenen-
Maurizio Mammuccini ha esperienza decennale nella progetta-
zione e sviluppo di software. Dedica particolare attenzione alle do sempre presente la sintesi
tecnologie di calcolo distribuito. Utilizza sin dalle primissime versioni espositiva, cercherò di appro-
il Visual Studio di Microsoft. Attualmente è formatore per PCS fondire – in continuità col pre-
Umbria a Perugia e consulente per aziende del settore informatico.
È MCSD for VS6 - MCDBA for Sql Server 2000 - MCAD for .NET
cedente [10] – la trattazione del-
- MCSD for .NET ed MCT. Vive e risiede in Umbria. Può essere le architetture di eventi in COM
contattato all’indirizzo mmammuccini@infomedia.it e .NET e come in tale ambito il

34 VBJ N. 69 - Maggio/Giugno 2006


ENTERPRISE

.NET Framework renda possibile una ottima di riutilizzo di componenti software, ossia di
interoperabilità. file binari al cui interno sono state compila-
Soprattutto in questa prima puntata presen- te funzionalità molto particolari.
terò un’utile panoramica a coloro che hanno Cerchiamo di descrivere sinteticamente
l’esigenza di comprendere l’utilizzo event-dri- quanto appena enunciato. Partiamo dal con-
ven di un componente COM in .NET. cetto di interfaccia così come stabilito nella
programmazione OOP (Object Oriented Pro-
Perché ancora COM? gramming): un’interfaccia non è altro che una
Perché interessarsi a COM, dover conoscere collezione di prototipi (o sintassi) di funziona-
la maniera in cui COM implementa la propria lità esposte da un qualche manufatto.
architettura di eventi, come .NET la traduce, Perché un’interfaccia è così importante nel-
visto che c’è .NET? la programmazione ad oggetti? L’intento del-
Ecco qualche risposta personale: l’OOP è quello di incapsulare, entro classi, dati
e funzionalità sui dati, in modo da nascondere
1. COM non è ‘morto’; gli attuali sistemi ope- all’esterno i dettagli di implementazione (al-
rativi Microsoft lo prevedono ancora al loro goritmi) di queste funzionalità [10].
interno ed esso continua ad essere un’otti- Ciò non perché si intenda soltanto custodi-
ma infrastruttura a componenti binari per re gelosamente i segreti degli algoritmi, ben-
macchine Windows, senza nulla togliere a sì perché ciò che ci interessa in una classe è
.NET. quali funzionalità essa realmente mette a di-
2. Esiste un po’ ovunque (anche in Italia) sposizione e non come effettivamente le im-
un immenso patrimonio di software bina- plementi al suo interno. Ciò ai fini del riutiliz-
rio scritto per COM (es. in Visual Basic, zo del software, che sostanzialmente significa
in C++, in MFC, in ATL) ed implementa- riutilizzo di dati ed operazioni su quei dati.
to dentro applicazioni anche grandi e co- Quindi l’idea è di raccogliere le funzionalità
stose, la cui corretta migrazione a .NET ri- in un costrutto (appunto l’interfaccia) e por-
chiede che si affrontino le tematiche espo- lo a disposizione di chiunque voglia imple-
ste nell’articolo. mentare quelle funzionalità in un manufatto
3. Gli argomenti sono comunque belli di per binario. Per un riutilizzatore è sufficiente la
sé, al di là dell’utilità o meno della loro trat- conoscenza delle interfacce esposte al fine di
tazione espositiva. stabilire se quel manufatto possa o meno es-
sere impiegato in un progetto.
Comunque deve essere chiaro che nel pros- La scrittura di un’interfaccia in uno specifico
simo futuro il design del nostro patrimonio linguaggio dipende dal particolare costrutto
di applicazioni dovrà necessariamente es- formale che tale linguaggio implementa. Ciò
sere aggiornato o riprodotto completamen- vale anche per la realizzazione del manufat-
te avendo come target la piattaforma .NET e to. Spesso in Microsoft Windows le interfacce
a tale scopo bisogna capire come COM vada vengono implementate in classi (es. in C++)
ad interoperare con .NET a livello di gestio- e queste compilate entro DLL.
ne di eventi. Visto che stiamo trattando COM, vogliamo in
questa parte discutere un po’ di come COM in-
COM tenda le interfacce; questo è un punto delicato
È data per acquisita una minima conoscen- per tutti i ragionamenti che seguiranno.
za della tecnologia Microsoft COM; comun- Il protocollo COM di Microsoft impone uno
que ricordiamo che COM (Component Object standard binario per le interfacce, ossia ne
Model) è uno standard binario ad interfacce, stabilisce il layout binario di memoria. Ciò
proprietario Microsoft, pensato e realizzato ha una profonda conseguenza concettuale so-
per fornire una maniera potente ed efficace prattutto per quei programmatori provenien-

N. 69 - Maggio/Giugno 2006 VBJ 35


ENTERPRISE

poi, tranquillamente, essere compilata dal


compilatore MSIDL ad esempio in una li-
breria di tipi (TLB). Avendo a disposizione
i tipi interfaccia in una TLB possiamo scri-
verne l’implementazione in un componente
o più. Chiudiamo questa parte con due uti-
li osservazioni.
Figura 1 Diagramma componente-interfaccia
Prima: la rappresentazione grafica di un com-
ponente che implementa un’interfaccia COM,
in cui viene esaltato il disaccoppiamento, sen-
za scindere il relativo legame tra l’interfaccia
ti dal C++; un’interfaccia COM non è la stes- esposta e la scatola nera, poiché in binario,
sa cosa, a livello binario, di una comune in- del relativo componente implementante è mo-
terfaccia di classe, vale a dire della collezio- strata in Figura 1, dove la scatola indica pro-
ne dei membri pubblici di una classe (solita- prio l’oscuramento dei dettagli d’implemen-
mente funzioni). Non è la stessa cosa dell’in- tazione dei metodi e l’accesso alle funziona-
terfaccia di una DLL, ossia della totalità delle lità nel componente mediato da un’interfac-
funzioni esportate dalla DLL. cia (lo spillo).
Un’interfaccia COM è essenzialmente una Seconda: di solito gli sviluppatori di compo-
definizione dell’aspetto (layout) che un set di nenti COM seguono l’approccio object orien-
funzionalità dovrà avere in memoria. ted per la loro realizzazione, ossia le interfac-
Dunque, come nel caso generale, un’interfac- ce vengono implementate da oggetti (ogget-
cia COM individua un insieme di funzioni che ti COM) scritti poi nel componente. Queste
dovranno essere implementate in un compo- classi assumono il nome di coclassi. Comun-
nente e che dei client potranno utilizzare. que non è strettamente necessario seguire
Un componente COM, per un client, è sol- questa strada, in quanto il componente può
tanto l’implementazione binaria di un insie- esser scritto in un linguaggio qualunque, an-
me di interfacce COM ed è per il tramite di che non-OOP.
queste che il client può invocare le funziona- Concludiamo questa sezione dell’articolo
lità distribuite con il componente. ricordando alcune definizioni che ci saran-
Oltre al fatto che un client stabilisce il con- no utili in seguito, gli identificatori univer-
tatto con il componente puntandone un’in- sali in COM.
terfaccia esposta, bisogna anche tener conto Come esseri umani attribuiamo ad esempio,
che le funzionalità stesse implementate sono alle coclassi od alle interfacce COM, dei nomi
in binario, quindi il client trascura i detta- per noi chiari, leggibili e pronunciabili.
gli d’implementazione delle funzionalità nel COM non utilizza (o meglio non predilige)
componente, in particolare non interessano questi nomi human-readable per tener trac-
al client i dettagli del particolare compilato- cia di queste entità, soprattutto a livello di re-
re utilizzato per compilare il componente. In gistro di sistema.
definitiva non interessa al client in quale lin- COM vuole assegnato un nome a coclas-
guaggio il componente sia stato scritto. si, interfacce, librerie, ecc. che sia un GUID
Si potrebbe pensare a client Visual Basic o (Globally Inique Identifier), più precisamen-
Visual C++ che tramite interfacce COM acce- te un numero intero su 128 bit in un partico-
dono a componenti COM scritti in C++. lare formato Microsoft che sfrutta il sistema
Le interfacce COM hanno un loro linguag- di numerazione esadecimale per la sua com-
gio preferenziale di descrizione, il MSIDL posizione. Nell’SDK di Windows viene fornito
(Microsoft Interface Definition Language). un generatore di GUID a vari livelli.
La definizione d’interfaccia COM data può I GUID nel caso di interfacce sono detti

36 VBJ N. 69 - Maggio/Giugno 2006


ENTERPRISE

IID (Interface Identifier)


od identificatori di inter-
faccia, mentre per le clas-
si COM questi interi son
detti CLSID (Class Iden-
tifier) od identificatori di
classi. I GUID in virtù del
loro algoritmo generatore Figura 2 Comunicazione unidirezionale tra un oggetto COM ed un suo client
sono unici. Per ulteriori
utili approfondimenti su
COM, rimandiamo ad una
delle opere citate in bibliografia ([3] [9]) Una simile comunicazione viene instaurata
dal client ricorrendo a precise API di COM,
Richiami sull’architettura come ad esempio la potentissima CoCreateIn-
ad eventi di COM stance (o la sua estensione CoCreateInstan-
Esponiamo sinteticamente come COM orga- ceEx) che consente l’istanziazione dell’oggetto
nizzi il proprio modello d’eventi. COM in memoria e la relativa valorizzazione
Il modello di funzionamento di base in COM nel client di un puntatore d’interfaccia espo-
è sempre il medesimo e possiamo riassumer- sta dall’oggetto istanziato.
lo nel seguente schema: Dunque il problema che COM si pone nell’ar-
chitettare la propria infrastruttura ad eventi
1. un client costruisce in memoria un oggetto è come sia possibile strutturalmente imple-
COM ottenendo un puntatore ad una par- mentare una comunicazione in senso contra-
ticolare interfaccia di questi; rio a quella che va dal client all’oggetto COM,
2. dal puntatore d’interfaccia ottenuto, il ciò perché nell’emettere una notifica al client
client invoca funzionalità listate nell’in- l’oggetto deve poterlo ‘richiamare’.
terfaccia puntata o migra ad un’altra in- Prima di esporre come COM risolva questo
terfaccia esposta dall’oggetto istanziato; problema, dobbiamo introdurre ancora un po’
3. l’oggetto COM esegue la funzionalità ri- di terminologia.
chiesta ed eventualmente restituisce un Relativamente ad un oggetto COM, lo stan-
risultato. dard COM distingue due tipologie d’inter-
facce: interfacce in ingresso ed interfacce
Ai fini della nostra trattazione possiamo os- in uscita.
servare che un simile tipo di comunicazione Un’interfaccia in ingresso (incoming inter-
tra l’oggetto COM ed il suo client è sempre face) è la norma per un oggetto COM ed è
unidirezionale (one way communication) e per il suo tramite, come già osservato pri-
ciò perchè è il client che stabilisce la comu- ma a proposito della CoCreateInstance, che
nicazione con l’oggetto COM inviando a que- un client può stabilire una comunicazione
sti una richiesta di esecuzione di un oppor- con l’oggetto.
tuno servizio. Le interfacce in ingresso costituiscono colle-
La Figura 2 evidenzia con il senso delle frec- zioni di sintassi di funzionalità implementa-
ce l’unidirezionalità di questa comunicazio- te dagli oggetti COM che possono venir pun-
ne; si noti come il client punti con la freccia tate dai rispettivi client. Tramite le interfac-
un’interfaccia (indicata con il simbolo di uno ce in ingresso gli oggetti COM diventano de-
spillo) esposta dall’oggetto COM. gli interessanti oggetti d’utilizzo pratico nel-
Al contrario non si osserva nessuna freccia le applicazioni.
che, uscendo dall’oggetto COM, si diriga ver- Come già detto, COM prevede anche un’al-
so il client. tra tipologia d’interfaccia che gioca un ruolo

N. 69 - Maggio/Giugno 2006 VBJ 37


ENTERPRISE

MSIDL utilizza l’attri-


buto source per indica-
re un’interfaccia in uscita
di un oggetto COM, ossia
per indicare quell’inter-
faccia che poi dovrà ve-
Figura 3 Comunicazione bidirezionale tra un oggetto COM ed un suo client
nir implementata da un
client, se questi vuol esse-
re richiamato per ricevere
fondamentale nel proprio modello di eventi, dall’oggetto COM notifiche d’evento.
l’interfaccia in uscita.
Un’interfaccia in uscita (outgoing interface, MSIDL
anche detta interfaccia d’origine) permette coclass ClassCOMWithCallback
ad un oggetto COM di richiamare il proprio {
client per notificargli un messaggio, ossia per [source] ICallback;
informarlo dell’originarsi di un qualche even- };
to nella propria storia.
Un’interfaccia in uscita è definita da un og- La dichiarazione precedente specifica che
getto COM ed implementata, se vogliamo la ICallback è un’interfaccia in uscita della co-
bidirezionalità di comunicazione, dai relati- classe (classe di oggetto COM) denominata
vi client. ClassCOMWithCallback.
Nel caso di una comunicazione bidireziona- Se non premettessimo l’attributo source al
le tra due oggetti COM, diciamoli Object1 ed nome dell’interfaccia, allora la classe COM
Object2, dobbiamo fare in modo che l’ogget- ClassCOMWithCallback dovrebbe fornire codi-
to che richiama esponga una o più interfac- ce ai metodi della Icallback, perché compre-
ce in uscita. sa nella lista delle interfacce esposte entro le
Nel caso in cui l’oggetto COM richiamante parentesi graffe.
sia Object2 possiamo rappresentare la situa- L’attributo source invece indica al compila-
zione come in Figura 3, dove Object2 defini- tore MSIDL che l’interfaccia ICallback è una
sce un’interfaccia in uscita, ICallback, il client sorgente di notifiche di evento e che l’interfac-
Object1 la implementa in modo che Object2 cia viene richiamata invece che implementa-
possa richiamare Object1 appunto invocan- ta dall’oggetto ClassCOMWithCallback.
done un opportuno metodo. La classe COM ClassCOMWithCallback effet-
Sinteticamente il descrivere un’interfaccia tuerà dunque invocazioni ai metodi di que-
in uscita per un oggetto COM significa che sta interfaccia.
l’oggetto COM sa poi come agire da client Il gioco è dunque fatto: gli oggetti COM pub-
nei confronti di un relativo client che la im- blicano interfacce di callback che dovranno
plementa. essere implementate ed istanziate dai rispet-
ICallback è quindi un’interfaccia d’uscita tivi client, che tramite esse potranno ricevere
per Object2, mentre è un’interfaccia in in- le necessarie notifiche d’evento.
gresso per Object1. Ogni client di un oggetto COM dovrà quindi
La descrizione di un’interfaccia in uscita per istanziare un oggetto appropriato che si fac-
un oggetto COM avviene, come per ogni altra cia carico d’implementare i metodi dell’in-
interfaccia COM, in MSIDL, linguaggio uffi- terfaccia di callback d’uscita pubblicata dal-
ciale per scrivere le interfacce COM. La defi- l’oggetto COM.
nizione d’interfaccia COM data può poi, tran- Questi particolari oggetti forniti da un client
quillamente, essere compilata ad esempio in di un oggetto COM vengono denominati ogget-
una libreria di tipi (TLB). ti sink. Un oggetto sink (raccoglitore d’eventi)

38 VBJ N. 69 - Maggio/Giugno 2006


ENTERPRISE

presente nel client è dun-


que un oggetto che imple-
menta almeno una parti-
colare interfaccia in uscita
(sink interface) pubblicata
dall’oggetto COM a cui il
Figura 4 Notifica d’evento tramite un oggetto sink
client chiede servizi.
In COM tramite un og-
getto sink la sorgente può
emettere notifiche d’evento al client, così IConnectionPoint è quello di permettere il
come evidenziato in Figura 4. passaggio dal client all’oggetto COM di un
Componenti COM od oggetti COM in grado puntatore al sink del client, implementante
di richiamare il client sfruttando un oggetto la particolare interfaccia d’uscita che l’ogget-
sink fornito da quest’ultimo, secondo lo sche- to COM intende utilizzare.
ma appena esposto, vengono detti oggetti con- Ciascun punto di connessione è strutturato
nettibili o collegabili (connectable objects); in modo da supportare – e non implementa-
spesso nella letteratura del settore in lingua re – una specifica interfaccia in uscita, e sol-
inglese si trova connectable components. tanto quella (Figura 5).
Chiariamo ora come secondo COM un og- Fra i vari metodi dell’interfaccia IConnec-
getto collegabile possa venire collegato ad un tionPoint quello tramite il quale viene sta-
client, in modo da poterlo poi richiamare tra- bilito il collegamento tra il client e il compo-
mite un’opportuna interfaccia di uscita. nente COM è Advise.
L’aggancio tra un oggetto collegabile ed un Il metodo Advise viene invocato dal client
suo client passa per i fondamentali punti di dell’oggetto per fornire all’oggetto collegabile
connessione (connection point) una tecnica pu- un puntatore (IUnknown *pUnk) alla basilare in-
ramente object oriented dove il punto di con- terfaccia IUnknown implementata dal sink del
nessione (o di contatto) gestito dall’oggetto col- client in modo che l’oggetto connettibile possa
legabile è in realtà esso stesso un oggetto. eseguire per prima cosa l’invocazione pUnk->
I punti di connessione sono dunque, come QueryInterface(iidICalback, ...) per ot-
detto, oggetti COM (implementanti l’interfac- tenere indietro un puntatore all’interfaccia
cia IConnectionPoint). di callback, da utilizzare successivamente
Il principale scopo dell’interfaccia COM per le eventuali notifiche al client.

Figura 5 Notifica d’evento tramite un oggetto sink

N. 69 - Maggio/Giugno 2006 VBJ 39


ENTERPRISE

La sorgente d’evento tiene appeso un col- dove riid è l’identificatore dell’interfaccia


legamento stabilito con l’Advise come scrit- d’uscita su cui è chiesto un punto di con-
to sopra, fintantochè il client non lo inter- nessione, mentre ppCP è il puntatore di tipo
rompa con un’invocazione al metodo Unadvi- IConnectionPoint che verrà valorizzato su di
se (sempre definito nell’interfaccia IConnec- un preciso indirizzo nel caso questo punto di
tionPoint). connessione esista.
Eseguito ciò, il metodo Advise passa al client Anche qui chiudiamo il richiamo all’architet-
un numero intero identificatore unico, nel sen- tura ad eventi di COM, rimandando sempre
so che identificherà univocamente il client alle opere citate in bibliografia ([3] [9]).
per l’oggetto collegabile. Questo intero è noto
come il cookie del client e viene conservato Assembly d’interoperabilità ed utilizzo
dal client per poi essere ripassato all’oggetto di componenti COM in .NET
collegabile durante la fase di disconnessione .NET possiede un ambiente di runtime mol-
con Unadvise. to organizzato. Questo ambiente runtime di
I metodi dell’interfaccia COM IConnec- .NET (CLR) permette al programmatore .NET
tionPoint consentono dunque, nell’architet- di astrarre i meccanismi di basso livello di una
tura ad eventi COM, ad un client di collegar- specifica piattaforma reale di esecuzione di
si e scollegarsi ad un componente collegabi- codice binario, concentrandosi soltanto sugli
le. Nell’ottica ed organizzazione di questa ar- specifici meccanismi del runtime di .NET.
chitettura ad eventi vi è un’altra fondamenta- Non dimentichiamo che .NET Framework
le interfaccia sulla quale dobbiamo spendere è diffuso per le principali piattaforme opera-
qualche parola: l’interfaccia IConnectionPoin- tive per vari sistemi operativi (es. Windows,
tContainer. Linux , Mac OS) quindi esistono specifiche
Essa permette l’interrogazione di un compo- versioni di CLR tutte compatibili con le spe-
nente collegabile sui punti di connessione im- cifiche Microsoft.
plementati da quest’ultimo, cercando di otte- Inoltre il CLR ha una propria gestione del-
nere informazioni utili in tal senso. la memoria durante l’esecuzione del codice.
Per mezzo della IConnectionPointContainer I client di componenti COM infatti, devono
possiamo localizzare uno specifico punto di preoccuparsi della gestione del lifetime del-
connessione relativamente ad uno specifico IID l’istanza del componente rilasciandolo quan-
d’interfaccia o comunque produrre un’enume- do non più utile, mentre i client di compo-
razione di tutti i punti di connessione imple- nenti .NET non debbono preoccuparsi di ciò,
mentati dal componente. In breve, dunque, l’in- essendo il CLR a gestire il rilascio della me-
terfaccia IConnectionPointContainer permette moria occupata dal componente non più uti-
di stabilire se un componente COM collegabi- lizzato.
le dispone di interfacce d’uscita. Sempre a proposito di gestione di memo-
L’importante metodo FindConnectionPoint ria, il CLR è libero di spostare gli oggetti al-
per esempio, a fronte di un IID d’interfaccia locati e quindi riassegnare i riferimenti ad
d’uscita passato in input valorizza, o meno, essi. Quest’ultimo fatto è problematico per
un puntatore ad un punto di connessione ver- i client non gestiti, poiché questi confidano
so l’interfaccia. sul fatto che l’oggetto resti sempre nella stes-
La sintassi del metodo FindConnectionPoint sa posizione.
è Queste ed altre differenze simili danno luo-
go ai cosiddetti problemi d’interoperabilità
HRESULT FindConnectionPoint( COM/.NET.
REFIID riid, Tali problematiche vengono superate grazie
IConnectionPoint **ppCP agli assembly d’interoperabilità.
); Si immagini un componente COM di nome

40 VBJ N. 69 - Maggio/Giugno 2006


ENTERPRISE

Questi oggetti svolgono un servizio basilare


in tutta l’architettura d’interoperabilità .NET\
COM, ossia effettuano il marshaling (smista-
mento) degli argomenti trasferiti nelle chia-
mate a metodo tra il codice gestito e quello
non gestito, verso l’oggetto COM di cui effet-
tuano il wrapping.
Dunque gli RCW sono oggetti che hanno la
Figura 6 COMServer.dll capacità di varcare i confini tra il codice gesti-
to e quello non gestito, gestendo tutti i mec-
canismi di basso livello come appunto la tra-
sformazione dei tipi dato (Figura 7).
COMServer.dll al cui interno è scritto l’ogget- Servendosi dei metadati scritti nell’IA ot-
to COM COMObj. tenuto da una libreria dei tipi (TLB), il CLR
Nella Figura 6 è rappresentata graficamen- istanzia sia l’oggetto COM interessato che il
te questa situazione. suo wrapper.
La dll COM COMServer.dll ed i tipi scritti al Attenzione al fatto notevole che è vero che
suo interno hanno una struttura organizzata per ogni oggetto COM c’è un rispettivo RCW
in binario non direttamente comprensibile al istanziato, ma per uno stesso oggetto COM,
runtime .NET. indipendentemente dalle sue istanze in me-
Allo scopo di un loro utilizzo, è necessa- moria utilizzate, viene istanziato ed utilizzato
ria una forma comprensibile al runtime di un unico RCW che ne effettua il wrapping.
.NET. L’RCW svolge un altro importante servizio:
Nel codice gestito .NET gli oggetti COM sono il gestore del conteggio dei riferimenti d’in-
resi disponibili in MSIL entro particolari as- terfaccia all’istanza dell’oggetto COM che in-
sembly detti assembly d’interoperabilità od capsula.
IA (Interoperability Assemblies). L’RCW infatti gestisce una cache di puntatori
Sulla produzione di questi assembly parle- ad interfaccia sull’oggetto COM ed è quindi in
remo più avanti nell’articolo. grado di rilasciare l’oggetto COM deallocandone
L’assembly IA non sostituisce fisicamente le risorse di memoria occupate quando non più
la dll COM (es. la COMServer.dll corrispon- utile. L’RCW stesso quando non più utilizzato
dentemente alla quale è stato prodotto) della viene predisposto per la Garbage Collection.
quale costituisce una sua formulazione .NET Fra gli IA primeggiano i PIA (Primari Inte-
e le classi scritte al suo interno non sostitui- roperability Assemblies), ossia gli assembly
scono gli oggetti COM che descrivono, ma d’interoperabilità primari.
vanno a configurarsi come intermediari fra Un PIA viene realizzato dallo stesso produt-
il codice gestito ed il codice non gestito in tore della libreria dei tipi di un componente
cooperazione. COM e viene firmato univocamente in modo
Le classi scritte nell’IA corrispondenti a clas- che possa finire nella GAC (Cache degli as-
si COM vengono dette wrapper (incapsulato- sembly) del sistema che lo utilizzerà.
ri) d’interoperabilità. Benché corrispondentemente ad una stessa
In questa prima puntata trattiamo gli RCW libreria di tipi COM possono esistere più as-
(Runtime Callable Wrapper) ossia oggetti sembly d’interoperabilità, uno solo di questi
.NET che vengono istanziati dal CLR pre- può essere un PIA per la libreria.
via lettura dei rispettivi metadati scritti nel- Di solito sono i fornitori della libreria che di-
l’IA, ogni volta che in codice gestito invo- stribuiscono il PIA relativo da utilizzare e, se di-
chiamo funzionalità negli oggetti COM cor- sponibili, noi dovremmo utilizzare questi piut-
rispondenti. tosto che produrne direttamente di nostri.

N. 69 - Maggio/Giugno 2006 VBJ 41


ENTERPRISE

Figura 7 RCW

Importazione di librerie COM mo al progetto, by References, un riferimento


in progetti .NET ad una determinata libreria di tipi COM.
Un problema fondamentale che spesso si Il tool a riga di comando TlbImp.exe forni-
manifesta a coloro che intendono riutilizzare to gentilmente dalla Microsoft con l’SDK di
componenti COM in .NET, è quello di far ve- .NET Framework è un altro modo di consegui-
dere tipi COM (interfacce, classi, strutture…) re lo stesso risultato. L’utilità TlbImp.exe è in-
che di solito sono scritti dentro librerie bina- fatti in grado di convertire una libreria di tipi
rie – le TLB – a potenziali utilizzatori .NET. COM in relativi metadati .NET, producendo
La visione del tipo COM è da intendersi fina- un componente binario .NET (quindi scritto
lizzata senz’altro ad un suo utilizzo in codi- in MSIL) che può venir utilizzato, previa sua
ce gestito .NET, quindi alla possibilità di re- referenziazione nel progetto, da un qualun-
ferenziare detti tipi nel codice. que linguaggio .NET compatibile.
In codice gestito per poter referenziare tipi La sintassi dell’importer di librerie di tipi
COM – come ad esempio interfacce o classi è questa:
– dobbiamo includerne la relativa definizio-
ne .NET. tlbimp tlbFile [options]
Il modo più immediato è quello di utilizzare
Visual Studio stesso, in grado di generare un dove alcune importanti utili opzioni le tro-
assembly d’interoperabilità quando aggiungia- viamo elencate nella Tabella 1.

Tabella 1 Opzioni da riga di comando di TlbImp.exe

Opzione Descrizione
/? Visualizza l’help del comando d’utilità
/keyfile:filename Firma l’assembly con la chiave fornita in filename
/namespace:namespace Indica lo spazio dei nomi per l’assembly
/out:filename Specifica il nome dell’assembly prodotto
/primary Rende l’assembly prodotto un PIA (Primari Interoperability Assembly)

42 VBJ N. 69 - Maggio/Giugno 2006


ENTERPRISE

Ad esempio C#
public enum REGKIND
tlbimp CPPObject.dll /out: CPPObjectInt.dll {
REGKIND_DEFAULT = 0,
genera l’assembly d’interoperabilità CP- REGKIND_REGISTER,
PObjectInt.dll corrispondente alla dll COM REGKIND_NONE
CPPObject.dll. } //REGKIND
Comunque anche l’utilità TlbImp.exe per
quanto importante ed utile non rimane l’unico VB.NET
strumento per esporre tipi COM in .NET. Private Enum RegKind
Inoltre, nello spazio dei nomi System.Run-
time.InteropServices viene fornita la classe RegKind_Default = 0
TypeLibConverter che mette a disposizione RegKind_Register = 1
metodi estremamente efficaci per la conver- RegKind_None = 2
sione delle coclassi e delle interfacce di una
libreria dei tipi in metadati entro assembly. End Enum ‚REGKIND
Questa API .NET è in grado di generare gli
stessi metadati prodotti da TlbImp.exe. A dif- dove la descrizione dei valori d’enumerazio-
ferenza però della TlbImp.exe, la classe Type- ne è riportata nella Tabella 2.
LibConverter è in grado di convertire in meta- Detto ciò evidenziamo inoltre che la clas-
dati soltanto una libreria dei tipi in memoria, se TypeLibConverter dispone di due fonda-
ossia precedentemente caricata in memoria mentali metodi per conseguire la conversio-
ad esempio con la potentissima WIN32 API ne desiderata:
LoadTypeLibEx. • ConvertAssemblyToTypeLib – Converte un as-
La LoadTypeLibEx permette infatti di cari- sembly .NET in una libreria di tipi COM
care in memoria una libreria di tipi ed op- • ConvertTypeLibToAssembly – Converte una
zionalmente ne permette la registrazione nel libreria di tipi COM in un assembly .NET
registro di sistema. Cerchiamo quindi ora di approfondire un
È bene prevedere di utilizzare la LoadType- po’ il meccanismo di generazione via co-
LibEx piuttosto che la LoadTypeLib in quanto dice .NET dell’assembly d’interoperabilità
quest’ultima registra comunque la libreria. che vede coinvolta l’API TypeLibConverter,
Per specificare la modalità o meno di regi- a partire da una libreria COM.
strazione della libreria specifichiamo in input Nel codice che segue e che vede utilizzata la
alla LoadTypeLibEx un valore tratto da una classe TypeLibConverter faremo ricorso al me-
enumerazione, la REGKIND fornita nell’SDK todo ConvertTypeLibToAssembly (che poi è lo
di Windows. stesso metodo utilizzato sia da Visual Studio
Diamo qui per facilitare la lettura e com- che dall’utilità a riga di comando TlbImp.exe
prensione del codice che seguirà, questa enu- per produrre assembly d’interoperabilità).
merazione: Per prima cosa, visto che dobbiamo carica-
re a runtime in memoria una libreria binaria,
typedef enum tagREGKIND{ dobbiamo collocare nel codice .NET la dichia-
REGKIND_DEFAULT, razione dell’API LoadTypeLibEx, a tal scopo si
REGKIND_REGISTER, dia uno sguardo al Listato 1.
REGKIND_NONE DLLImport così come utilizzato nei brani di
} REGKIND; codice precedenti è un utilissimo attributo che
permette di far vedere al nostro codice gestito
la cui traduzione in C# e Visual Basic.NET .NET, l’API LoadTypeLibEx scritta nella libre-
è: ria DLL non gestita oleaut32.dll.

N. 69 - Maggio/Giugno 2006 VBJ 43


ENTERPRISE

L’attributo DLLImport ha
Tabella 2 Significato dei valori di enumerazione REGKIND
tra i suoi utilizzi appun-
to quello di permettere la
referenziazione di funzio- Valore Descrizione

ni esterne a .NET che ad REGKIND_DEFAULT Utilizza il default di registrazione


esempio possono trovarsi REGKIND_REGISTER Registra la libreria
in librerie non gestite. REGKIND_NONE Non registra la libreria
Subito dopo aver intro-
dotto la definizione della
LoadTypeLibEx dovremo in-
vocarla per caricare in memoria la TLB di no- LoadTypeLibEx(fileTlb,REGKIND.REGKIND_NONE,
stro interesse ed ottenere un riferimento ad out tlbToImport);
essa. VB.NET
‘ Invocazione in VB.NET della LoadTypeLibEx
C#
// Invocazione in C# della LoadTypeLibEx Dim fileTlb As String = collocazione della
libreria compreso nome ed estensione tlb;
string fileTlb = collocazione della libreria Dim tlbToImport As UCOMITypeLib = Nothing;
compreso nome ed estensione tlb; LoadTypeLibEx(fileTlb, REGKIND.REGKIND_NONE,
UCOMITypeLib tlbToImport = null; tlbToImport)

Figura 8 Oggetto clsBoolean realizzato in VB6

44 VBJ N. 69 - Maggio/Giugno 2006


ENTERPRISE

Listato 1 Dichiarazione in C# dell’API LoadTypeLibEx

C#
// Dichiarazione in C# dell’API Win32 LoadTypeLibEx
public enum REGKIND
{
REGKIND_DEFAULT = 0,
REGKIND_REGISTER,
REGKIND_NONE
} //REGKIND

[DllImport(“oleaut32.dll”, CharSet=CharSet.Unicode)]
public static extern void LoadTypeLibEx(string strTypeLibName,
REGKIND regKind,
out UCOMITypeLib TypeLib);

VB.NET
‘ Dichiarazione in VB.NET dell’API Win32 LoadTypeLibEx
Private Enum RegKind

RegKind_Default = 0
RegKind_Register = 1
RegKind_None = 2

End Enum ‚REGKIND

<DllImport(„oleaut32.dll“, CharSet:=CharSet.Unicode)> _
Private Shared Sub LoadTypeLibEx(ByVal strTypeLibName As [String],
ByVal regKind As RegKind,
<MarshalAs(UnmanagedType.Interface)> ByRef typeLib As [Object])
End Sub

Se la chiamata a funzione ha successo, in en- una libreria di tipi COM, passando per l’uti-
trambi i casi di codice otteniamo la valorizza- lizzo della classe TypeLibConverter è piutto-
zione di un riferimento (tlbToImport) alla li- sto laboriosa se paragonata agli altri due me-
breria COM in memoria. todi precedentemente esposti.
Il passo conclusivo è quello di ottenere l’as- Se si dispone di Visual Studio o comunque
sembly d’interoperabilità e salvarlo su disco utilizzando l’utilità TlbImp.exe fornita nel-
pronto per essere utilizzato fattivamente. l’SDK di .NET Framework, possiamo conse-
Per conseguire quest’ultimo risultato non guire lo stesso risultato in minor tempo e con
dobbiamo far altro che istanziare la TypeLib- minor scrittura di codice.
Converter ed invocarne il metodo Convert- Concludiamo questo paragrafo evidenziando
TypeLibToAssembly. che il metodo ConvertTypeLibToAssembly del-
L’esecuzione del metodo ConvertTypeLi- la classe TypeLibConverter necessita di un pa-
bToAssembly restituisce un oggetto di classe rametro (che non può essere null o Nothing)
System.Reflection.Emit.AssemblyBuilder che che costituisca un riferimento ad istanza di
tramite il relativo metodo Save ci permette il una classe implementante l’interfaccia Itype-
salvataggio su file-system dell’assembly d’in- LibImporterNotifySink.
teroperabilità ottenuto (Listato 2). L’interfaccia ITypeLibImporterNotifySink di-
Come vediamo la tecnica di produzione di un chiara e mette a disposizione un meccanismo
assembly d’interoperabilità .NET a partire da di callback per il convertitore della libreria

N. 69 - Maggio/Giugno 2006 VBJ 45


ENTERPRISE

Listato 2 Salvataggio in C# dell’assembly d’interoperabilità

C#
// Salvataggio in C# dell’assembly d’interoperabilità
TypeLibConverter conv = new TypeLibConverter();
string FileName = nome; //nome dell’assembly prodotto con estensione dll
string assemblyName = destinazione //destinazione dell’assembly prodotto;
AssemblyBuilder intAssembly = conv.ConvertTypeLibToAssembly(tlbToImport,
assemblyName + “\\” + FileName,
0, new SinkToITypeLibImporter(),
null, null, false);
//salvataggio
intAssembly.Save(FileName);

VB.NET
‘ Salvataggio in VB.NET dell’assembly d’interoperabilità
Dim conv As TypeLibConverter = New TypeLibConverter()
Dim FileName As String = nome ‘nome dell’assembly prodotto con estensione dll
Dim assemblyName As String = destinazione //destinazione dell’assembly prodotto
Dim intAssembly As AssemblyBuilder = conv.ConvertTypeLibToAssembly(tlbToImport,
assemblyName + “\” + FileName,
0, New SinkToITypeLibImporter(),
Nothing, Nothing, False);
‘salvataggio
intAssembly.Save(FileName);

dei tipi, in modo da informare il chiaman- Si tenga presenta a tal scopo il codice del-
te sullo stato della conversione, così da coin- l’oggetto CPPObject scritto nella dll COM CP-
volgerlo attivamente nell’intero processo di PObject.dll allegato a questo articolo. Per i
conversione. programmatori Visual Basic si tenga presen-
Ovviamente si possono fornire implemen- te il codice dell’oggetto VBObject scritto nel-
tazioni di questa interfaccia a seconda di la dll COM VBObject.dll. I due oggetti sono
come si vuole controllare l’intero svolgimen- quasi identici a parte alcune differenze, do-
to della produzione dell’assembly d’intero- vute alle profonde differenze tra i linguaggi
perabilità. Visual C++ 6 (VC++) e Visual Basic 6.
Nel codice del Listato 3 non ci interessa di Il componente COM C++ è stato ricava-
essere coinvolti nella fase di conversione e for- to utilizzando l’infrastruttura Microsoft ATL
niamo un sink implementato banalmente. 3.0 in Visual C++ 6.0, mentre il componente
A questo punto dell’articolo abbiamo ormai COM Visual Basic è stato ricavato utilizzan-
capito come il .NET Framework permetta l’uti- do Visual Basic 6.0.
lizzo di eventi notificati da componenti COM, L’oggetto comunque incapsula una sola va-
a client .NET. riabile di stato di tipo booleano che viene
modificata e letta tramite una proprietà di
Mappatura in assembly .NET nome Valore.
di eventi di componenti COM e gestione Quando lo stato dell’oggetto cambia (a segui-
early-binding in codice gestito to della modifica del campo booleano incap-
In questa parte dell’articolo cercheremo di sulato), allora scatta la notifica al client del-
chiarire come vengono interpretati e trascrit- l’evento onStatusChanged.
ti dentro un assembly .NET, gli eventi di un In VC++ l’oggetto in questione pubblica
oggetto COM pubblicati in una libreria dei un’interfaccia d’uscita _IBooleanoEvents con-
tipi. tenente il solo metodo onChangedStatus, la

46 VBJ N. 69 - Maggio/Giugno 2006


ENTERPRISE

cui invocazione permetterà di notificare il uuid(0C9350C8-6AD1-4E6F-A906-C62F224DE50F),


client che la implementa in un opportuno helpstring(“Booleano Class”)
oggetto sink, secondo quanto esposto in pre- ]
cedenza. coclass Booleano
Le due interfacce esposte dall’oggetto COM {
in MSIDL sono mostrate nel Listato 4, mentre [default] interface IBooleano;
l’oggetto stesso è così definito in MSIDL [default, source] dispinterface
_IBooleanoEvents;
MSIDL };
// Oggetto Booleano
[ e come ben si può vedere, l’interfaccia d’usci-

Listato 3 Implementazione in C# della ITypeLibImporterNotifySink

C#
// Implementazione banale in C# della ITypeLibImporterNotifySink

private class SinkToITypeLibImporter : ITypeLibImporterNotifySink


{
Assembly ITypeLibImporterNotifySink.ResolveRef(object typeLib)
{

return null;
}

void ITypeLibImporterNotifySink.ReportEvent(ImporterEventKind eventKind,


int eventCode,
string eventMsg)
{
//non implementata
}
}

VB.NET
‘ Implementazione banale in VB.NET della ITypeLibImporterNotifySink

Private Class SinkToITypeLibImporter


Implements ITypeLibImporterNotifySink

Public Function ResolveRef(ByVal typeLib As Object) As System.Reflection.Assembly Implements


System.Runtime.InteropServices.ITypeLibImporterNotifySink.ResolveRef

Return Nothing

End Function

Public Sub ReportEvent(ByVal eventKind As


System.Runtime.InteropServices.ImporterEventKind,
ByVal eventCode As Integer,
ByVal eventMsg As String) Implements
System.Runtime.InteropServices.ITypeLibImporterNotifySink.ReportEvent
‘non implementata
End Sub

End Class

N. 69 - Maggio/Giugno 2006 VBJ 47


ENTERPRISE

Listato 4 Interfaccia in ingresso IBooleano

MSIDL
// Interfaccia in ingresso IBooleano
[
object,
uuid(98EEE356-88FB-476D-9531-601B774E91C1),
dual,
helpstring(“IBooleano Interface”),
pointer_default(unique)
]
interface IBooleano : IDispatch
{
[propget, id(1), helpstring(«Legge e scrive il valore booleano incapsulato»)]
HRESULT Valore([out, retval] BOOL *pVal);
[propput, id(1), helpstring(“Legge e scrive il valore booleano incapsulato”)]
HRESULT Valore([in] BOOL newVal);
};

// Interfaccia in uscita _IBooleanoEvents


[
uuid(1258DA8B-27DD-4C80-ABBE-4B7127C1C138),
helpstring(“_IBooleanoEvents Interface”)
]
dispinterface _IBooleanoEvents
{
properties:
methods:
[id(1), helpstring(“Notifica il cambiamento di stato”)]
HRESULT onChangedStatus([in] BOOL* pVal );
};

ta _IBooleanoEvents è dichiarata con l’attribu- implementato in un’opportuna classe pro-


to source, proprio come evidenziato preceden- xy appositamente realizzata dall’infrastrut-
temente. Nell’implementazione dell’oggetto in tura ATL.
una classe C++, la notifica dell’evento viene Quest’ultimo è l’effettivo metodo notifican-
implementata con il seguente codice: te il client.
In Visual Basic 6 le cose sono molto più sem-
C++ plici, basti guardare l’intero codice della classe
‘ implementazione C++ della notifica d’evento COM (scritta in un modulo di classe clsBoo-
if(newVal!=(BOOL)this->m_value) lean) che viene realizzato in ambiente Visual
{ Basic 6.0 (Listato 5).
//imposta il valore incapsulato dentro m_value Il compilatore Visual Basic 6 ci nasconde
this->m_value=newVal; molti dettagli simili a quelli appena visti in
VC++, direttamente da lui gestiti, nell’imple-
Fire_onChangedStatus(&(newVal)); mentazione dell’oggetto COM.
Per esempio l’interfaccia d’uscita __clsBoo-
} lean (doppio underscore iniziale) è direttamen-
te definita nel compilato dal compilatore, inse-
dove m_value è il campo booleano incapsu- rendo al suo interno la definizione dell’evento
lato nella classe C++ CBooleano corrispon- void StatusChanged([in, out] VARIANT_BOOL*
dente alla coclasse Booleano dell’IDL. La no- pValue); in perfetto stile MSIDL.
tifica passa per l’invocazione al metodo HRE- A conferma di ciò si può osservare la Figu-
SULT Fire_onChangedStatus(BOOL * pVal) ra 9.

48 VBJ N. 69 - Maggio/Giugno 2006


ENTERPRISE

Listato 5 Intero codice della classe COM

VB6
‘Variabile o variabili locali per la memorizzazione dei valori delle proprietà.
Private mvarValore As Boolean ‘Copia locale.
‘evento di notifica
Public Event StatusChanged(pValue As Boolean)

Public Property Let Valore(ByVal vData As Boolean)

If vData <> mvarValore Then


‘scrive il nuovo valore del campo booleano
mvarValore = vData
‘notifica il cambiamento di stato passando il nuovo valore del campo
‘booleano
RaiseEvent StatusChanged(mvarValore)

End If

End Property

Public Property Get Valore() As Boolean


‘legge il valore del campo booleano incapsulato
Valore = mvarValore

End Property

Vediamo infatti da essa che il compilatore de- La parola chiave WithEvents fornita dal Visual
finisce la coclasse clsBoolean come una clas- Basic nella dichiarazione del reference all’og-
se COM che implementa le due interfacce, _ getto, permetterà in compilazione la scrittu-
clsBoolean (singolo underscore iniziale) con- ra del codice di creazione di un sink che im-
tenente la proprietà Valore come interfaccia plementa le interfacce d’uscita descritte dal-
d’ingresso e l’interfaccia d’uscita __clsBoo- l’oggetto collegabile.
lean con il metodo di notifica d’evento di- Però non ci interessa qui ed ora produrre un
chiarata al suo interno. client VB6 o VC++ 6 di questi oggetti, bensì
Val la pena osservare che dal punto di vi- di vederne uno realizzato in .NET (ad esempio
sta dei linguaggi OOP questo modo di fare in C# o in VB.NET) cercando di capire come
del compilatore Visual Basic è poco ortodos- possano essere tradotti e gestiti gli eventi sol-
so, visto che molti dettagli di strutturazione levati dall’oggetto COM.
OOP del codice vengono tolti al program- Ebbene, in questa sezione dell’articolo ve-
matore (anche perché VB6 come linguaggio diamo l’utilizzo di un assembly d’interopera-
non ne è dotato intrinsecamente) e delega- bilità così da collegarci early-binding al com-
ti al compilatore in una successiva fase di ponente.
compilazione. Nella successiva seconda puntata dell’arti-
In entrambi gli oggetti prodotti – sia quel- colo vedremo un metodo altrettanto interes-
lo in VC++ 6 che in VB6 – viene pubblica- sante ma a mio avviso di minor impatto sul-
ta un’interfaccia in uscita in corrisponden- le prestazioni runtime che sfrutta il late-bin-
za della quale, se vogliamo essere richiama- ding al componente, ossia non passa per la
ti, nel client dovremo fornire il relativo sink produzione di un assembly d’interoperabilità
d’eventi. nel collegamento all’oggetto COM.
Questo in Visual Basic 6 è molto semplice. Applicando, come detto in precedenza,

N. 69 - Maggio/Giugno 2006 VBJ 49


ENTERPRISE

l’utilità T l b I m p . e x e
produciamo l’assem-
bly d’interoperabili-
tà CPPObjectInt.dll al
componente COM CP-
PObject.dll.
Si può procedere nel-
lo stesso modo alla pro-
duzione dell’assembly
d’interoperabilità an-
che per il componen-
te scritto in VB6. A li-
vello binario per il CLR
di .NET i due assem-
bly sono identici, eccet- Figura 9 Disassemblato MSIL del componente d’interoperabilità
to nelle differenze dei
nomi delle entità scrit-
te all’interno che riflet-
tono in modo ovvio le identiche differenze di faccia d’uscita _IBooleanoEvents è stata rea-
nomi nei componenti originari. lizzata una corrispondente classe con il nome
Ci concentriamo dunque sull’assembly d’in- così strutturato
teroperabilità CPPObjectInt.dll.
Ricorrendo al disassemblatore Ildasm fornito NomeInterfacciaDiUscita_NomeMetodoEventHandler
con l’SDK di .NET Framework osserviamo che
le interfacce IBooleano (interfaccia d’ingres- Questa classe estende la System.Multica-
so) ed _IBooleanoEvents (interfaccia in uscita) stDelegate; per ogni metodo nell’interfaccia
vengono importate nell’assembly come inter- in uscita è stato creato nell’assembly d’intero-
facce gestite a tutti gli effetti, mantenendo gli perabilità un delegato opportuno ([10]).
stessi nomi che hanno nel componente COM Dalla Figura 11 notiamo che le sintassi dei
e con gli stessi membri dichiarati nell’inter- metodi nell’interfaccia d’uscita sono mante-
faccia (Figura 10). nute nelle classi delegate corrispondenti, con
Si osservi che per ogni metodo nell’inter- la sola sostituzione del nome in Invoke e la
trasformazione dei tipi
non gestiti nelle contro-
parti gestite.
Nell’assembly d’inte-
roperabilità (Figura 12)
troviamo inoltre l’inter-
faccia _IBooleanoEven-
ts_Event e le due clas-
si _IBooleanoEvents_
EventProvider (privata)
ed _IBooleanoEvents_
SinkHelper.
La classe con suffisso
_SinkHelper implemen-
Figura 10 Eventi COM come delegati in .NET
ta l’interfaccia .NET _
IBooleanoEvents for-

50 VBJ N. 69 - Maggio/Giugno 2006


ENTERPRISE

Figura 11 Internals delle classi ed interfacce nell’assembly d’interoperabilità

nendo il tipo per il sink che raccoglierà le leano (ingresso) ed IBooleanoEvents_Event


notifiche d’evento (si osservi che questa clas- (uscita).
se incapsula il campo intero m_dwCookie che La classe che effettivamente dovrà essere
l’istanza riceverà dall’oggetto COM trami- istanziata per veder prodotta l’istanza della
te RCW). classe COM è la BooleanoClass che imple-
La classe _IBooleanoEvents_EventProvider menta la classe astratta Booleano. Si faccia
è responsabile dell’interfacciamento tramite attenzione al fatto che la BooleanoClass im-
RCW con il meccanismo dei punti di connes- plementa i metodi ricevuti dalla IBooleanoE-
sione nel componente COM e tiene traccia vents_Event (add_XXX e remove_XXX) sfruttan-
dei vari sink che hanno sottoscritto di voler do l’implementazione che di questi metodi
essere notificati, tramite il campo ArrayList viene fornita nella classe privata _IBoolea-
m_aEventSinkHelpers. noEvents_EventProvider.
L’interfaccia _IBooleanoEvents_Event (che Possiamo dunque utilizzare l’istanza della
osserva la regola d’attribuzione del nome No- classe BooleanoClass per sottoscrivere le noti-
meInterfacciaDiUscita_Event) è l’esatta tradu- fiche d’evento ed ogniqualvolta nel client, tra-
zione in .NET dell’interfaccia d’uscita COM _ mite gli operatori (es. in C#) += (od in VB.NET
IBooleanoEvents. AddHandler) od -= (od in VB.NET RemoveHan-
Dentro quest’interfaccia son compresi gli dler) aggiungiamo o rimuoviamo la gestione
stessi membri (gli eventi) esattamente come di una notifica d’evento utilizziamo i metodi
nell’interfaccia COM, ma dichiarati utilizzan- add_XXX e remove_XXX nella classe _IBoo-
do i delegati scritti nell’assembly stesso cor- leanoEvents_EventProvider.
rispondentemente agli eventi COM.
Nell’assembly d’interoperabilità è scritta Conclusioni
una classe astratta denominata Booleano che Nella prossima puntata prenderemo in con-
eredita da tutte e due le interfacce IBoo- siderazione argomenti interessanti come:

N. 69 - Maggio/Giugno 2006 VBJ 51


ENTERPRISE

∑ gestione .NET late binding di eventi nei [2] Julian Templeman e John Paul Muel-
componenti COM ler – “COM programming with Microsoft
∑ CCW (COM Callable Wrapper) ed interope- .NET”, Microsoft Press, 2003
rabilità di componenti .NET in COM [3] Guy Eddon ed Enry Eddon – “Inside Di-
∑ Considerazioni finali sull’interoperabilità stribuited COM”, Mondadori Informati-
COM/.NET ca, 1998
[4] George Sheperd e Brad King – “Inside
Sono grato alle opere citate in bibliografia i cui ATL”, Mondadori Informatica, 1999
autori mi hanno aiutato a comprendere e poi a [5] Jeffrey Richter, Francesco Balena “Program-
mettere in pratica i concetti della moderna pro- mazione avanzata con Microsoft Visual Ba-
grammazione distribuita a componenti, secondo sic .NET” Mondadori Informatica, 2002
gli standard industriali della Microsoft. [6] http://msdn.microsoft.com/library/default.
Invito l’attento lettore ad approfondire su asp?url=/library/en-us/csref/html/vcref-
questi libri i concetti discussi nel presente thedelegatetype.asp
articolo, sperando che oltre all’acquisizione [7] http://msdn.microsoft.com/library/default.
di tecniche e metodologie, egli possa perce- asp?url=/library/en-us/csref/html/vcwlke-
pire l’intrinseca bellezza dei contenuti con- ventstutorial.asp
cettuali. [8] http://msdn2.microsoft.com/en-us/library/
75s611wc.aspx
Bibliografia e Riferimenti [9] E. Deana – “IUnknown, CLSID, IDispatch,
[1] Jeffrey Richter – “Microsoft .NET Pro- IID”, Visual Basic Journal n. 29
grammazione avanzata”, Mondadori In- [10] M. Mammuccini – “ .NET: Delegate e model-
formatica, 2002 lo di eventi”, Visual Basic Journal n. 66

52 VBJ N. 69 - Maggio/Giugno 2006


.NET TOOLS
Snippet Editor niente altro che semplici file XML che seguono
di Fabio Perrone uno schema determinato. Risulta quindi possibi-
le scrivere a mano i propri snippet oppure è più
Uno strumento gratuito per creare e semplice ricorrere a strumenti esterni quali il pro-
gestire i code snippet tagonista del nostro articolo.
La prima volta che si esegue il nostro tool, è ne-
Una delle caratteristiche su cui è stato profu- cessario popolare il treeview con i code snippet
so uno sforzo maggiore in Visual Studio 2005 è puntando alla cartella di default in cui vengono
l’aumento di produttività da parte dello svilup- installati da Visual Studio, tipicamente [Percor-
patore tramite nuove funzionalità e nuovi stru- so di installazione di Visual Studio]\VB\Snippets.
menti messi a disposizione da Microsoft, tra i A questo punto, la prima caratteristica da met-
quali spiccano senza dubbio i code snippet. Esu- tere in evidenza è che premendo con il tasto de-
la dagli scopi di questa recensione stabilire se il stro del mouse su un qualsiasi nodo, è possibile
singolo sviluppatore preferisca scrivere “da sé” eliminare il nodo stesso, aggiungere una nuova
ogni singola riga di codice oppure farsi “aiuta- cartella (cioè un raggruppamento logico di snip-
re” dallo strumento di sviluppo. Si presume co- pet), oppure aggiungere un nuovo snippet. Poi-
munque vi sia grande unanimità nello stabilire ché l’eliminazione dello snippet è irreversibile,
che lo sforzo compiuto a Redmond per inserire si raccomanda di utilizzare questa caratteristi-
caratteristiche come i code snippet sia assoluta- ca con molta cautela! Alla destra del treeview
mente apprezzabile. contenente tutti gli snippet, sono presenti due
I code snippet non sono altro che frammenti panel: uno con l’editor dello snippet in cui si
di codice riutilizzabile, in grado di eseguire dei scriverà lo snippet vero e proprio o si studiano
compiti con una difficoltà che varia da semplice snippet esistenti e il preview dello snippet, cioè
a intermedia, magari ripetitivi, con la semplice la possibilità di esaminare l’aspetto dello snip-
pressione di due tasti. Per compiti semplici e ri- pet esattamente come apparirà in Visual Stu-
petitivi si intende la definizione di una proprie- dio; l’altro contenente un tabstrip che permette
tà, la dichiarazione di un evento o la definizione di personalizzare ulteriormente lo snippet, tra-
di un metodo pubblico; compiti leggermente più mite l’impostazione di numerose proprietà che
complessi possono essere l’utilizzo di ADO.NET ora andremo ad analizzare brevemente. Il primo
o decrittare una stringa. tab, “Properties”, permette di impostare caratte-
Gli snippet possono essere scritti con tre fi- ristiche generali dello snippet, quali il titolo, la
nalità ben precise: creare snippet generalizzati descrizione, l’autore, il linguaggio (VB, C#, J#
per la comunità degli sviluppatori; creare snip- o XML), lo scope.
pet personalizzati per essere utilizzati all’interno Poiché la vera forza degli snippet consiste non
di un’azienda o solo da un singolo sviluppatore; solo nello scrivere parti di codice “pronte all’uso”,
creare snippet per insegnare i costrutti di un lin- ma anche fornire una flessibilità tale da poter
guaggio ai neofiti. modificare immediatamente (personalizzandolo)
Fondamentalmente, i code snippet non sono un frammento di codice, il secondo tab (“Repla-

54 VBJ N. 69 - Maggio/Giugno 2006


.NET TOOLS

Figura 2 Snippet Editor

cement”) permette di descrivere quali parti del- tomaticamente gli Imports e i riferimenti neces-
lo snippet possono essere variate dinamicamen- sari per un suo corretto funzionamento. In que-
te una volta inserito nel codice. sto caso ci vengono in aiuto i tab “References” e
“Imports” che permettono di assolvere in modo
estremamente semplice a questo compito. L’ulti-
mo tab, “Test”, permette di compilare lo snippet
I code snippet non sono e controllare così se sono stati prodotti degli er-
niente altro che semplici rori durante la creazione.
La semplice Toolbar permette di salvare lo snip-
file XML che seguono uno pet (con estensione .snippet), di esportare lo snip-
schema determinato pet in un file con estensione .vsi (cioè Visual Stu-
dio Installer, quindi distribuibile a terzi), e di im-
postare le opzioni per l’applicazione, quali il font
e l’aspetto. Poiché il progetto è assolutamente
Dato che la filosofia di base degli snippet è sem- open source, non è da sottovalutare l’opportuni-
plificare al massimo la scrittura di codice e acce- tà (per i più curiosi) di scaricare il codice sorgen-
lerare i tempi di sviluppo, una volta richiamato te direttamente dal workspace di Snippet Editor
uno snippet è compito dello stesso inserire au- su gotdotnet.

N. 69 - Maggio/Giugno 2006 VBJ 55


.NET TOOLS

Grazie all’estrema semplicità dello Snippet Edi-


BugTracker.Net
tor, è possibile essere produttivi con il tool in po-
di Raffaele Di Natale
chi minuti: questa è una caratteristica da non
sottovalutare perché sovente, durante la stesura
del codice, è necessario scrivere velocemente uno Un’applicazione web-based per la gestione
snippet che automatizzi la scrittura di codice al- ed il tracciamento dei bug. E molto di più
tamente ripetitivo.
In questi ultimi mesi grande pubblicità è stata
fatta nel mondo Microsoft circa i nuovi sistemi di
sviluppo che non rappresentano più semplicemen-
Poiché l’eliminazione te degli IDE, ma integrano in maniera completa
dello snippet è irreversibile, importanti funzionalità di gestione del codice sor-
gente e del lavoro in team. Per i professionisti e
si utilizzi questa le aziende medio-piccole che nell’immediato non
caratteristica con cautela hanno programmato un passaggio a tali sistemi,
BugTracker.NET può rappresentare la soluzione
ideale per la gestione di bug e di incident.

Anche se numerosi, gli snippet presenti in Vi- L’applicazione


sual Studio non possono soddisfare le esigenze di BugTracker.NET è una web application gratuita,
ogni singolo sviluppatore. Fortunatamente, con interamente sviluppata in C#, che offre servizi di
la loro estensibilità è possibile raggiungere un gestione di bug per progetti software. L’imposta-
notevole livello di personalizzazione per scrive- zione web-based dell’applicazione risulta partico-
re dei frammenti di codice che vengano incontro larmente utile, soprattutto nei casi in cui i team di
alle esigenze di ognuno. Grazie ad uno strumen- sviluppo, o gli utenti che rilevano e/o registrano le
to di grandissima utilità come lo Snippet Editor difettosità del software, si trovano distribuiti sul
(ricordiamo che è assolutamente gratuito) la per- territorio. L’autore ha puntato senz’altro sulla faci-
sonalizzazione può permettere alla produttività lità d’uso e su una forte integrazione con i servizi
di compiere un gran balzo in avanti. di posta elettronica, così come ogni buon software
di bug-tracking richiede. BugTracker.NET si basa
Prodotto essenzialmente sui seguenti componenti:
Visual Basic Snippet Editor
Url di riferimento l overLIB [1], una libreria in JavaScript, pensata
http://msdn.microsoft.com/vbasic/downloads/tools/snippeteditor per arricchire le applicazioni web, o più in ge-
Stato Release nerale siti web, con piccole finestre di popup
Stabile simili alle tooltip di Windows, per favorire la
Semplicità d’uso ™™™™™ navigazione all’interno del sito stesso e forni-
Una semplice interfaccia utente permette di essere immediata- re al contempo suggerimenti circa la funzione
mente produttivi che si sta selezionando. È stata utilizzata per
Utilità ™™™™≤ la visualizzazione di un data-picker;
Semplifica drasticamente la creazione e la gestione degli snippet. l POP3Client.cs [2], rappresenta il codice relativo
Qualità prodotto ™™™™≤ all’omonima classe POP3client che implementa
Affidabile, nei test sul prodotto eseguiti non ha mai mostrato par- come metodi tutti i comandi standard POP3;
ticolari problemi.
l SharpMimeTools [3], un assembly open sour-
Qualità documentazione ™™™≤≤ ce compatibile sia con .Net sia con Mono per il
Non è presente nessun help integrato con l’applicazione; un buon
help è tuttavia disponibile on line nel workspace dello Snippet Edi-
parsing e la decodifica dei messaggi MIME;
tor su Gotdotnet (in lingua inglese). l log4net [4], il consueto tool di supporto alla
programmazione.

56 VBJ N. 69 - Maggio/Giugno 2006


.NET TOOLS

Figura 1 La pagina di amministrazione dell’applicazione

BugTracker.NET richiede il .Net Framework Nel primo caso basterà eseguire lo script setup.
1.1, SQL o MSDE ed un server web. La versio- sql mediante QueryAnalyzer e solo in seguito si
ne descritta nel presente articolo è stata testata potrà modificare il file web.config nella parte re-
su Windows XP SP2 con IIS, .Net Framework 1.1 lativa alla connessione al database. Nel secondo
ed MSDE 8.0. caso sarà invece necessario effettuare qualche pas-
so in più. Infatti, dopo aver modificato la stringa
Installazione di connessione predefinita come in:
Per cominciare bisogna effettuare il download del
pacchetto dal sito [5]. La prima fase dell’installazio- <add key=”ConnectionString” value=”server=(local);
ne consiste nel creare una directory virtuale su IIS database=MASTER;uid=sa;pwd=mypwd”/>
che chiameremo BtNet: indirizzeremo pertanto la
nostra applicazione mediante http://localhost/btnet/. basterà andare alla pagina http://localhost/btnet/
Il passo successivo consiste nel creare l’apposito da- query.aspx e creare il database usando la consue-
tabase che sarà successivamente utilizzato dall’ap- ta sintassi Sql
plicazione. Come suggerito nella documentazione
tecnica, i casi possibili sono essenzialmente due: CREATE DATABASE BTNET

1. creazione e configurazione di un database con (BTNET è fornito solo a scopo d’esempio) e solo
SQL; successivamente tornare a modificare la chia-
2. creazione e configurazione di un database con ve ConnectionString della pagina web.con-
MSDE. fig settando il nome prescelto per il database.

N. 69 - Maggio/Giugno 2006 VBJ 57


.NET TOOLS

A questo punto non resta che


fare copia-incolla del contenu-
to di setup.sql all’interno del-
la text-area della pagina query.
aspx ed eseguire lo script clic-
cando sul pulsante “Execute
SQL”. Nel caso in cui si vuo-
le rendere disponibile l’appli-
cazione in un server web pub-
blico è importante rimuovere
tale pagina, per ovvie ragio-
ni, e modificare la chiave Al-
lowQueryEditingForNonAd-
mins impostandola a 0.

Figura 3 Il form relativo alla creazione di un nuovo bug


L’ambiente di lavoro di
BugTracker.NET
Il primo login può essere ef-
fettuato usando la coppia admin/admin per user- Bug, che passione!
name e password. Dopo il primo accesso è chia- Tramite la voce bug si accede alla pagina che con-
ramente consigliato modificare la password. È sente di inserire i nuovi bug o di effettuare ricer-
facile notare che l’ambiente di lavoro eccelle in che mirate, per esempio visionare i bug aperti, con
accessibilità e consente una completa persona- la possibilità di stampare tale elenco o di espor-
lizzazione delle proprie funzioni per venire in- tarlo verso Excel. In Figura 3 è descritto il form
contro alle più svariate esigenze. Vediamo nei di inserimento di un nuovo bug in cui si possono
dettagli alcune delle funzionalità più importanti notare il campo per la descrizione breve, il campo
e originali. Come descritto in Figura 2, la parte per la priorità e lo stato e l’area di testo per i com-
superiore della pagina presenta le voci di menu menti, modificabile nella dimensione attraverso i
che consentono di operare con la nostra appli- pulsanti “+” e “-”. Una funzionalità utilissima per
cazione. La più importante è senz’altro la voce chi fa davvero uso di un sistema di bug-tracking è
admin, mediante la quale accediamo alla pagina la possibilità di realizzare dei collegamenti tra bug
di configurazione che ci consente di definire, tra diversi. Per far ciò è sufficiente scrivere tali colle-
l’altro, gli utenti, i progetti, le categorie, le prio- gamenti nell’area di testo destinata ai commenti
rità e gli stati possibili predefiniti (new, in pro- utilizzando il formato bugid#21, dove 21 è il nume-
gress, checked in, re-open, closed), tutti comple- ro del bug verso il quale si vuole realizzare il link.
tamente customizzabili. Un utente può sottoscrivere un dato bug e visio-
Fiore all’occhiello di BugTracker.NET è senz’al- nare anche l’elenco dei sottoscrittori.
tro la pagina dei report che, soprattutto per i È possibile inoltre allegare uno o più file al bug
team di sviluppatori che operano sotto sistema al fine di completarne la descrizione o come test di
di qualità, risulta uno strumento preziosissimo regressione; ciò è possibile solo se UploadFolder
per la facilità con cui si possono creare indica- di web.config è settato correttamente per puntare
tori e relativi grafici basati sulle informazioni a ad una directory che possa operare da repository (di
disposizione del progetto. Attraverso la voce set- default tale campo è fissato in c:\temp\upload).
tings si passa infine all’impostazione dei parame-
tri base dell’applicazione, primi fra tutti quelli Personalizziamo BugTracker.Net
relativi alla sottoscrizione delle comunicazioni L’intera applicazione è un continuo invito alla
via email legate agli inserimenti o alle modifi- personalizzazione. Per cominciare possiamo da
che sui bug. subito decidere di utilizzare BugTracker.NET non

58 VBJ N. 69 - Maggio/Giugno 2006


.NET TOOLS

come gestore di bug, ma come sistema di help- Conclusioni


desk. Infatti con poche modifiche in web.config, Le funzionalità offerte sono ben definite, effica-
BugTracker.NET non servirà più a tenere traccia ci e con pochi fronzoli. Questo spiega il grande
di bug, bensì di ticket aperti a fronte di richieste successo che riscontra ormai da tempo tra i suoi
effettuate per esempio da parte di clienti. utilizzatori che propongono continuamente nuo-
ve funzionalità o suggeriscono miglioramenti per
<add key=”AppTitle” value=”Customer Support”/> quelle esistenti, come facilmente si può rilevare
<add key=”SingularBugLabel” value=”Ticket accedendo alla sezione “Feature Request” di [6]. Il
<add key=”PluralBugLabel” value=”Tickets”/> numero di bug riscontrati e quelli risolti mettono
in evidenza la grande partecipazione a questo pro-
Un piccolo accorgimento adottato dallo svilup- getto software. Una curiosità: quale programma
patore che arricchisce sensibilmente la versatilità ha utilizzato l’autore prima di sviluppare BugTrac-
del software analizzato. Attraverso la pagina delle ker.Net? Risposta: phpBugTracker [7].
query, queryes.aspx, accessibile tramite l’omoni-
ma voce di menu, l’utente può intervenire diret- Riferimenti
tamente sulle query standard dell’applicazione [1] http://www.bosrup.com/web/overlib/
per modificarle oppure crearne di nuove. [2] http://www.codeproject.com/csharp/pop3client.
asp
[3] http://sourceforge.net/projects/sharpwebmail/
[4] http://logging.apache.org/log4net/
Le funzionalità offerte [5] http://btnet.sourceforge.net/bugtrackernet.
sono ben definite, html
[6] http://sourceforge.net/projects/btnet
efficaci e con pochi [7] http://phpbt.sourceforge.net/
fronzoli

Prodotto
Tali cambiamenti saranno visibili nel momento BugTracker.Net
in cui si accederà alla pagina dei bug per selezio- Url di riferimento
nare una particolare vista degli stessi. Ulteriori ed http://btnet.sourceforge.net/bugtrackernet.html
importanti cambiamenti alle impostazioni di base Stato Release
possono essere realizzati sia mediante le funzio- v.2.2.5
nalità dell’applicazione, sia tramite le key di web. Semplicità d’uso ™™™™™
config, tutte commentate e con esempi allegati. Chi ha utilizzato altri tool di bug-tracking noterà la notevole sem-
plicità d’uso. Per un utilizzo “standard” poco o nulla deve essere
fatto per cominciare a lavorare.
Limite dell’applicazione
Un’osservazione importante che i lettori devono Utilità ™™™™™
Un team composto da due o più persone difficilmente può fare a
tenere in considerazione è che, come dichiarato meno di un sistema come BugTracker.Net. È una di quelle applica-
dallo stesso autore di BugTracker.NET, l’applica- zioni che più si usano, più si apprezzano e più diventano utili.
zione è stata interamente sviluppata basandosi sul Qualità prodotto ™™™™≤
.Net Framework utilizzando un semplice editor di BugTracker.Net è una buona applicazione, scritta avvalendosi anche
testo. Ciò significa che del concetto di code-behind, di componenti esterni di massima qualità ed affidabilità.
alla base di qualsiasi applicazione ASP.NET svi- Qualità documentazione ™™™™≤
luppata in ambiente Visual Studio .NET, non c’è Bisognerebbe dare il massimo dei voti in quanto moltissimi sug-
gerimenti e chiarimenti sono presenti nella documentazione tec-
quasi traccia. Chi pensa di aggiungere dei nuovi nica del pacchetto di installazione. L’unico difetto è che tali infor-
moduli potrebbe incontrare qualche ostacolo dal mazioni risultano poco aggregate.
punto di vista dell’integrazione.

N. 69 - Maggio/Giugno 2006 VBJ 59


WEB

Analisi degli accessi


ad un sito web Seconda puntata
Tra i mezzi di comunicazione di massa il web è quello
che meglio si presta ad essere misurato; ma quanto sono
affidabili queste rilevazioni? E qual è il loro valore?

di Stefano Savo

N
ella prima puntata abbiamo visto i moti- presenti nella richiesta HTTP.
vi per i quali è utile analizzare il traffico Ai fini dell’analisi degli acces-
di un sito internet e quali dati è utile e si è importante che i file di log
possibile misurare; in questo secondo articolo cer- contengano le seguenti informa-
cheremo di vedere nel dettaglio quanto sono cer- zioni: data e ora, indirizzo IP del
ti questi dati e quanto l’affidabilità della rilevazio- richiedente, url richiesto, refe-
ne dipenda dalla scelta del modo più opportuno rer, cookie.
di misurare gli accessi. Vedremo poi alcuni fatto- A titolo di esempio ecco una
ri da considerare nella scelta del software di ana- possibile riga di un file di log:
lisi di tali dati.
I primi software di web analytics sono nati, ormai 192.168.1.3 jay.bird.com - fred
diversi anni fa, dall’analisi dei log dei web server. [25/Dec/1998:17:45:35 +0000]
Un web server riceve una richiesta HTTP e resti- “GET /~sret1/ HTTP/1.0” 200 1243
tuisce in risposta il documento richiesto, eventual- “http://www.site.com/” “Mozilla/
mente richiedendo ad un application server la ge- 2.0 (X11; I; HP-UX A.09.05)”
nerazione dinamica del documento sulla base dei
parametri presenti nella richiesta. I lettori più smaliziati avran-
Il web server annota anche in un apposito file di no già individuato due criticità
log le richieste HTTP ricevute e le loro caratteri- fondamentali di un’analisi che
stiche. si basi su questi dati:
Per ridurre le dimensioni dei file di log talvolta i
web server vengono configurati in modo tale che • L’indirizzo IP del richieden-
vengano riportate solo alcune delle informazioni te non è sempre disponibile
con certezza: molti utenti ac-
cedono al web tramite proxy
o firewall che mascherano
Stefano Savo è ingegnere informatico e lavora da più di l’IP dell’utente. In questi casi
cinque anni nella analisi, progettazione e sviluppo di web
diversi utenti che accedono
application. Tra i suoi interessi: Information Architecture e
Web Semantico. dalla stessa rete potrebbero
sembrare avere lo stesso IP.

N. 69 - Maggio/Giugno 2006 VBJ 61


WEB

Figura 1 Report generato da WebAlizer

• Non tutte le pagine che noi vediamo du- gine più viste che hanno la maggiore proba-
rante la navigazione di un sito internet bilità di essere cachate e conseguentemente
provengono dal web server. Quando richie- di non essere rilevate.
diamo una pagina già vista, la richiesta Se avete un’idea precisa di come i vostri
viene in molti casi soddisfatta dalla cache utenti accedano al sito (ad esempio perchè si
del browser e la richiesta non raggiunge tratta di un sito sulla intranet aziendale) po-
nemmeno il web server e quindi esso non tete valutare quanto questi problemi posso-
può annotarla nel file di log. Caso analo- no impattare sulle vostre analisi.
go si presenta quando gli utenti accedo- È comunque possibile considerare alcune
no ad internet attraverso un proxy (molto contromisure per evitare un’eccessiva distor-
frequente per gli utenti connessi alla rete sione dei dati.
aziendale). In questo caso non è nemme- Alcuni prodotti utilizzano l’indirizzo IP del
no necessario che l’utente abbia già visto visitatore in combinazione con la versione di
la pagina ma è sufficiente che uno degli browser utilizzata per identificare l’utente.
utilizzatori del proxy lo abbia fatto, affin- Questo accorgimento può servire a distingue-
chè il proxy stesso serva la pagina senza re due utenti che accedano al sito utilizzando
inviare la richiesta al web server remoto. lo stesso proxy ma browser diversi. Questa
soluzione può comunque non essere soddi-
L’indirizzo IP del richiedente è un dato che sfacente, ad esempio capita spesso che i di-
viene spesso usato per identificare l’utente, pendenti di un’azienda abbiano esattamen-
ma ciò comporta che gli utenti che accedo- te la stessa versione del browser ed utilizzi-
no usando lo stesso proxy rischiano di esse- no lo stesso proxy. È allora importante assi-
re considerati come un utente unico che vede curarsi che il software prescelto per l’anali-
moltissime pagine, falsando l’analisi. si dei log consenta di identificare una visita
Anche il caching di browser e proxy è poten- utilizzando altre informazioni. Un’informa-
zialmente molto dannoso: sono proprio le pa- zione che può utilmente essere utilizzata per

62 VBJ N. 69 - Maggio/Giugno 2006


WEB

Figura 2 Report generato da Analog

identificare con ragionevole certezza una visi- merosi accessi) vengono sorprendentemente
ta è l’identificativo di sessione che viene ge- implementate euristiche più approssimative
nerato dall’application server ed inviato dal ma più semplici. Se volete avere un’idea pre-
browser per tutte le richieste successive alla cisa dell’affidabilità dei dati calcolati da un
prima. Questo codice può essere memorizza- certo software è fondamentale a mio avvi-
to in un cookie o passato come parametro in so l’approccio sperimentale. Su un ambien-
ogni richiesta a seconda della vostra configu- te di test effettuate una decina di visite da
razione. In questo modo se avete un appli- varie macchine e fate analizzare il log così
cation server che gestisce le sessioni potete ottenuto dai vari software. In questo modo
calcolare in maniera sufficientemente affida- sapete quali risultati aspettarvi e probabil-
bile questo dato. Per la prima richiesta che mente vi sorprenderete nel vedere le diffe-
viene fatta in una visita però l’identificativo renze nei risultati calcolati dai vari tool, an-
di sessione non viene inviato dal browser al che da quelli che hanno avuto più successo
web server, in tal caso il software di analisi sul mercato.
può utilizzare diverse euristiche per cercare Nel corso del tempo ai sistemi di analisi dei
la prima pagina di ogni sessione. Ad esem- log si sono aggiunte altre soluzioni, che pre-
pio può partire dalla prima richiesta che con- vedono l’inserimento di apposito codice Java-
tenga un ID di sessione e cercare le richie- script nelle pagine erogate. Gli script vengo-
ste provenienti dallo stesso IP di poco ante- no eseguiti sul browser dell’utente ed invia-
cedenti o può utilizzare il referer per identi- no le informazioni al server, aggirando così il
ficare la pagina precedente. I prodotti leader problema della cache. Un’altro vantaggio di
di mercato spesso non indicano in maniera questi sistemi è che possono inviare le infor-
molto dettagliata l’algoritmo che applicano mazioni ad un server diverso da quello che
per identificare le pagine che appartengono eroga il sito web consentendo così di ester-
ad una sessione. Inoltre spesso per garanti- nalizzare il servizio di analisi degli accessi.
re un’alta velocità nell’analisi dei dati (che È nata così la possibilità di scegliere tra l’ac-
è sicuramente un aspetto importante per un quisto di un software da installare e quello
software destinato ad analizzare siti con nu- di un servizio di analisi. Alcuni servizi con-

N. 69 - Maggio/Giugno 2006 VBJ 63


WEB

sentono addirittura l’analisi in tempo reale tanti per la gestione tecnica del sito, come ad
degli accessi, che può essere un’informazio- esempio l’accesso da parte degli spider dei mo-
ne preziosa quando si vogliono gestire degli tori di ricerca (che solitamente non eseguono
eventi sul web. Questa possibilità non è tut- i Javascript) o, in caso di load balancing, qua-
tavia sempre così importante, sembra inve- le sia il carico sui diversi server.
ce fondamentale la possibilità di aggirare i Per concludere: è spesso utile combinare
problemi dovuti al caching. Tuttavia l’utiliz- un’analisi dei file di log con i dati generati
zo di un sistema basato sui Javascript client- dai Javascript client-side, ed infatti i softwa-
side comporta anche degli inconvenienti. Il re moderni quasi sempre supportano entram-
più grave ma forse quello meno importan- bi i sistemi di analisi.
te dal punto di vista numerico è che esisto-
no browser che non supportano Javascript e Assumendo quindi di aver fatto le scelte che
che in tutti browser è possibile disabilitare consentono la maggior correttezza possibile
l’esecuzione degli script. Questi utenti non dei dati raccolti, possiamo passare ad analiz-
verrebbero tracciati per nulla; tuttavia da zare altre qualità di un sistema di analisi de-
un punto di vista statistico la grande mag- gli accessi al sito.
gioranza degli utenti è in grado di eseguire Un fattore discriminante nella scelta del tool
i Javascript sul proprio browser e non li di- migliore può essere la flessibilità con la quale
sabilita. Un altro problema di questi sistemi il tool consente di definire gruppi di contenu-
è la limitazione nella possibilità di traccia- ti. È spesso utile infatti raggruppare insiemi
re l’uso di documenti che non possono ospi- di pagine per capire quali siano gli interessi
tare Javascript. Ad esempio per tracciare lo degli utenti e le modalità di utilizzo del sito.
scaricamento di un documento PDF, dovre- Valutando nel dettaglio le offerte dei diversi
mo inserire un Javascript sull’evento “oncli- software vediamo che molti impongono alcu-
ck” del link che punta al PDF. ni limiti in questa funzionalità: alcuni impon-
gono che le pagine di un gruppo appartenga-
no ad una stessa directory, altri consentono
di definire gruppi basandosi solo sull’uri del-
Un fattore discriminante le pagine e non sui parametri passati (e que-
sto può essere un problema per le pagine ge-
nella scelta del tool nerate dinamicamente); altri ancora impon-
migliore può essere gono che una pagina appartenga ad uno ed
un solo gruppo.
la flessibilità con la quale
il tool consente di definire Un’altra funzionalità distintiva consiste nel-
l’analisi dei path, ovvero dei percorsi seguiti
gruppi di contenuti dagli utenti nella navigazione.
Alcuni software si limitano ad identificare
le sequenze di pagine in una visita e a con-
tare il numero di visite composte dalle stes-
Questo consente di tracciare l’interesse al se pagine. Essendo molto difficile avere del-
documento, tuttavia richiede un attento in- le visite esattamente identiche nella sequen-
tervento del webmaster: se alcuni link non za di pagine, questo dato è spesso di difficile
sono configurati correttamente, le informa- lettura. Altri software invece effettuano una
zioni sulla navigazione non verranno mai re- vera e propria “cluster analysis” ovvero indi-
gistrate e saranno perse per sempre. viduano all’interno delle varie visite le sotto-
Con i Javascript client-side inoltre non è pos- sequenze più comuni e questo può essere un
sibile rilevare dati che possono essere impor- dato veramente interessante.

64 VBJ N. 69 - Maggio/Giugno 2006


WEB

Conclusioni Bibliografia
In generale le variabili da considerare nel- [1] Eric T. Peterson – “Web Site Measurement
l’analisi degli accessi ad un sito internet sono Hacks”, O’ Reilly, 2005
numerose proprio per l’eterogeneità caratte-
ristica di questo ambiente. Talvolta possiamo Riferimenti
fare delle assunzioni sul modo in cui gli uten- [2] WebTrends – www.netiq.com
ti accedono al servizio (con quali browser, con [3] NetTracker – www.sane.com
che configurazione, attraverso quali proxy) e [4] Summary – www.summary.net
semplificare in questo modo l’analisi, ma ciò [5] Urchin – www.urchin.com
non è sempre possibile. Non è possibile, in [6] Pilot Hit List – www.pilotsoftware.com
generale, avere la certezza di tracciare tutte [7] Analog – http://www.analog.cx/
le visite al sito ma è possibile avere delle im- [8] WebAlizer – http://www.mrunix.net/weba-
portanti indicazioni statistiche. Un’attenta va- lizer/
lutazione delle caratteristiche specifiche del [9] Pathalizer – http://pathalizer.sourceforge.net/
vostro ambiente e del vostro sito, e l’identifi- [10] http://www.clickz.com/experts/crm/actio-
cazione dei dati che vi interessa misurare vi nable_analysis/
consentirà allora di scegliere il software più [11] http://www.webanalyticsdemystified.com/
adatto per analizzare gli accessi al sito e per [12] http://www.coffeesuntechnology.com/
monitorare nel tempo i risultati. [13] http://www.hurolinan.com/

N. 69 - Maggio/Giugno 2006 VBJ 65