Anda di halaman 1dari 68

I N O F F E R TA V B J 7 0

Scrivi a
Building Scalable ASP.NET 2.0 Unleashed
Web Sites book@infomedia.it di S. Walther
di C. Henderson specificando
nell’oggetto della
O’ Reilly e-mail: Sams
ISBN 0596102356 ISBN 0672328232
348 pp - 39,99 € IN OFFERTA 1992 pp + CD - 52,95 €

VBJ n. 70
OPPURE
inviaci il coupon
Oracle HTML DB Windows Forms 2.0
Application Express sottostante Programming
di L. Linnemeyer e B.D. al numero di fax di C. Sells
Brown
0587/732232 Addison Wesley
ISBN 0321267966
Potrai acquistare 1292 pp - 52,95 €
Mc Graw Hill
ISBN 883864456X
i libri qui riportati con
540 pp - 43,00 € uno
SCONTO
CSS Mastery: Advanced
ECCEZIONALE Agile Software
Web Standards Solutions Construction
di A. Budd del 10% anche se di J. Hunt
acquisti solo un
libro Springer
Friends of ED ISBN 1852339446
ISBN 1590596145 OPPURE 254 pp - 65,47 €
280 pp - 43,70 €
del 20% se acquisti
3 libri

VBJ 70
online.infomedia.it
n. 70 - luglio/agosto 2006
bimestrale - anno dodicesimo

Direttore Responsabile
Marialetizia Mari (mmari@infomedia.it)
Direttore Esecutivo
ED I T O R I A L E
Il significato di
Francesco Balena (fbalena@infomedia.it)
Managing Editor
Renzo Boni (rboni@infomedia.it)
Collaboratori
“open source”
Raffaele Di Natale
Andrea Ferendeles
Fabio Perrone
Paolo Pialorsi
Gian Maria Ricci
O ggi ho partecipato a una riunione il cui scopo era decidere quali tecnologie utilizzare
per un applicativo di grandi dimensioni per la pubblica amministrazione. Come
spesso accade in questi casi, si era formato quasi naturalmente un
Justyn Roberts gruppo di dotnettiani e uno di javisti. In realtà l’accento non era
tanto sui linguaggi ma sulla filosofia di fondo, quindi chiamerò
questi ultimi gli opensourciani. Anche se è facile immaginare in
quale gruppo mi trovavo io, devo dire che il confronto è stato
costruttivo e mi ha permesso di imparare alcune cose che non
conoscevo.
La conclusione più interessante, però, non è stato tanto pesare
le ragioni dei due gruppi, quanto constatare quanto soggettiva
Direzione sia la definizione di open source, sia tra i suoi sostenitori che tra
Natale Fino (nfino@infomedia.it) i detrattori. C’è chi utilizza questo termine come sinonimo di gratuito, chi per indicare
Marketing & Advertising che i programmi open source sono forniti in sorgente, altri ancora per indicare che i fra-
Segreteria: 0587/736460 mework stessi sono disponibili in sorgente, chi sostiene che i linguaggi open source sono
marketing@infomedia.it
standard e non proprietari, e che sono supportati da una grande comunità di appassionati
Amministrazione che hanno sviluppato centinaia di componenti gratuite per tutti i gusti.
Sara Mattei Tutto vero. Peccato che anche il .NET Framework sia gratuito e fornito per il 90% in
(amministrazione@infomedia.it)
sorgente (con l’iniziativa SSCLI), che il C# sia uno standard ECMA, e che anche per .NET
Grafica esista una vastissima community che ha prodotto dei piccoli capolavori. Quanto al fatto di
(grafica@gruppoinfomedia.it)
fornire i sorgenti con le proprie applicazioni, quella ovviamente è una scelta degli svilup-
Technical Book patori (o è un vincolo contrattuale, come accade spesso con la pubblica amministrazione)
Lisa Vanni (book@infomedia.it) che è ovviamente utilizzabile anche con il software .NET (o Delphi, o VB6, ecc.)
Segreteria Nei fatti, non è affatto semplice definire cosa significhi realmente open source, soprat-
Enrica Nassi tutto se prendiamo in esame le numerose varianti di licenza disponibili in quel mondo.
(info@infomedia.it)
Le cose vanno persino peggio se si considerano le altre componenti che compongono una
tipica applicazione, ad esempio il database o i server applicativi. Incredibilmente, a volte
Stampa mi tocca spiegare che il database Oracle non è affatto gratuito (anzi!), anche se gira su
TIPOLITOGRAFIA PETRUZZI un sistema open source, come del resto non lo è neanche MySql nelle configurazioni in
Citta’ di Castello (PG) cluster. E viceversa, devo chiarire che Microsoft SQL Server Express non solo è gratuito
ma permette anche una migrazione assolutamente indolore verso il SQL Server “vero”
Ufficio Abbonamenti quando occorrono migliori prestazioni e scalabilità.
Tel. 0587/736460 - Fax 0587/732232
Non voglio essere frainteso. Io sono convinto che il movimento open source ha fatto
e-mail: abbonamenti@infomedia.it
www.infomedia.it molto e continuerà a fare moltissimo per il mondo IT. Ad esempio, ha fornito software ai
paesi del terzo e quarto mondo, dove una licenza di Windows Server 2003 costa quanto
Gruppo Editoriale Infomedia srl
Via Valdera P., 116 - 56038 Ponsacco (PI) Italia
lo stipendio annuale di un impiegato, e ha reso possibile la costruzione di computer da
Tel. 0587/736460 - Fax 0587/732232 100$ che contribuiranno in modo determinante alla crescita culturale ed economica di
red_vbj@infomedia.it quei paesi.
Sito Web www.infomedia.it
Ma se davvero vogliamo fare un discorso economico (e non ideologico), dovremmo
considerare il Total Cost of Ownership (TCO): una macchina Linux costa meno di un equi-
valente sistema Windows, ma la sua installazione e amministrazione richiede esperienze
ben più vaste di quelle in possesso di un impiegato “medio” di una azienda “media”. In un
mondo dove la manodopera (soprattutto se qualificata) costa tanto, risparmiare sul costo
Manoscritti e foto originali anche se non pubblicati, del software è davvero un buon affare come sembra?
non si restituiscono. È vietata la riproduzione
anche parziale di testi e immagini.
Francesco Balena www.dotnet2themax.it/blogs
Si prega di inviare i comunicati stampa e gli inviti stampa per
la redazione all’indirizzo: comunicatistampa@infomedia.it
Visual Basic Journal è una rivista di
Gruppo Editoriale Infomedia S.r.l. Via Valdera P, 116 Ponsacco - Pisa.
Registrazione presso il Tribunale di Pisa n. 20/1999
N. 70 - Luglio/Agosto 2006 VBJ 7
SOMMARIO
L U G L I O / A G O S TO

N.70 Editoriale
RUBRICHE

7
.NET Tools 61

SPECIALE
Windows Workflow Foundation 11
I componenti chiave di WinFX, la prossima versione di API managed per Windows
di Paolo Pialorsi

TECNICHE
CAPermutations: una libreria per risolvere problemi 19
combinatori
Regine, amazzoni e un'introduzione ai problemi combinatori.
di Francesco Balena

APPLICATIVI
.NET Sql Authorization Manager (NetSqlAzMan)
Un gestore di applicazioni sviluppate con il .NET Framework 2.0 27
di Andrea Ferendeles

C#
Generics in C# 2.0 45
L’introduzione della programmazione generica è sicuramente la novità più interessante del .NET 2.0, scopriamone
le caratteristiche principali.
di Gian Maria Ricci

MOBILE
Common Time mSuite Security 52
La programmazione orientata ai template enfatizza il riuso non solo dei componenti, ma anche delle loro modalità di utilizzo
di Lorenzo Vandoni

N. 70 - Luglio/Agosto 2006 VBJ 9


Windows Workflow Foundation

.NET 3.0: Windows


Workflow Foundation
Vediamo i componenti chiave di WinFX, la prossima
versione di API managed per Windows.

di Paolo Pialorsi (www.devleap.com)

C
ontinuiamo la serie di articoli dedica- quando scriviamo il codice delle
ti all’introduzione di WinFX, di recente nostre applicazioni, definiamo
rinominato .NET 3.0 da parte di Micro- dei flussi operativi/funzionali
soft. Come abbiamo già visto nel primo articolo che sono assimilabili a dei work-
di questa serie [1], .NET 3.0 è la prossima ver- flow. Pensiamo a tutti quei casi
sione di API managed per Windows, cioè basa- in cui farciamo il nostro codice
te sul .NET Framework di Microsoft, che vedrà di costrutti If, While, chiamate
la luce insieme a Windows Vista, ma che funzio- a metodi, a servizi esterni, ecc.
nerà anche su Windows XP Service Pack 2 e su in funzione dei requisiti funzio-
Windows Server 2003. nali che ci vengono indicati dal
In questo appuntamento concentriamo la nostra progetto in fase di sviluppo. In
attenzione su Windows Workflow Foundation realtà alle spalle di quel codice
(WF), il motore di workflow pensato per gestire, vi sono ragionamenti, diagram-
creare e descrivere flussi applicativi e processi mi di flusso e processi :in una
di business. parola, appunto, il “progetto”.
Spesso il problema che deriva
Perché WF dalla definizione di un proces-
so sotto forma di codice è il fatto
Il concetto di workflow in quanto tale è general- che quello stesso codice, rivisto
mente noto come flusso operativo/funzionale che magari anche solo alcuni mesi
descrive e controlla un processo di business, secon- dopo, se non è opportunamen-
do regole e percorsi definiti da un esperto del do- te commentato e documentato
minio di applicazione. Praticamente ogni giorno, diventa estremamente criptico.
Inoltre a volte il codice che gesti-
sce i flussi funzionali è annega-
to nel codice che gestisce l’inter-
Paolo Pialorsi, è un consulente e autore specializzato nello
sviluppo di servizi SOA e soluzioni in architettura distribuita faccia utente. Pensiamo ad una
basate sul Framework .NET di Microsoft. Lavora nell’omonima form nella quale un pulsante o
società Pialorsi Sistemi S.r.l. e fa parte del gruppo DevLeap. Può una textbox devono essere atti-
essere contattato via email: paolo@devleap.it. Mantiene il blog
personale all’indirizzo http://blogs.devleap.com/paolo/.
vati solo se l’utente sceglie una
determinata altra opzione, sem-

N. 70 - Luglio/Agosto 2006 VBJ 11


Windows Workflow Foundation

preconfezionati e ci darà la possibilità di de-


finirne altri. Noi stessi, come sviluppatori, po-
tremo prevedere all’interno delle nostre ap-
plicazioni il supporto per WF. Avremo quindi
un framework di workflow pervasivo e diffu-
so, che diventerà lo strumento principe per
coordinare i processi aziendali.

WinFx è un insieme di
librerie managed, per la
gestione delle applicazioni
del domani
Figura 1 Architettura di Windows Workflow
Foundadtion

pre disponibile nella form. Qualora dovessimo System e Human Workflow


realizzare un software con interfaccia utente In generale, prescindendo per un momento
sia web che Windows, con un approccio orien- da WF, i workflow sono di solito divisi in un
tato al codice, saremmo costretti a descrivere due macro-aree:
queste condizioni di abilitazione o disabilita- • System Workflow: descrivono processi di
zione dell’interfaccia, sia nel codice web che business che riguardano l’interazione e l’in-
in quello Windows. tegrazione tra sistemi. Sono ad esempio tut-
Ecco che uno strumento come Workflow ti quei flussi di scambio dati, o quei processi
Foundation ci consente invece di descrive in batch, che una volta descritti e implementati
forma grafica, attraverso dei designer di cui non richiedono interazioni dirette da parte di
poi parleremo, i flussi operativi delle nostre un utente, se non per configurarli e mandarli
applicazioni, collegandoli se necessario all’in- poi in esecuzione. Di solito hanno una durata
terfaccia utente, potendo però prescindere dal-
la particolare tipologia di strato di presenta-
zione (web, Windows, ecc.).
In questo modo possiamo concentrare dap-
prima la nostra attenzione sul flusso (Figura
3) per poi collegarlo all’eventuale interfaccia
utente applicativa, che diventa solo un detta-
glio rispetto alla logica che sta alla base del
prodotto software.
L’idea forte e vincente di WF è quella di ren-
dere disponibile il motore di workflow nel-
la gran parte dei prodotti software di Micro-
soft. Infatti WF sarà presente in Windows Vi-
sta, sarà installabile su Windows XP Service
Pack 2 e Windows Server 2003. Il prossimo
2007 Microsoft Office system ospiterà WF per Figura 2 I nuovi template di progetto per
la gestione di workflow documentali. Office Visual Studio e WF
Sharepoint Server 2007 offrirà dei workflow

12 VBJ N. 70 - Liglio/Agosto 2006


Windows Workflow Foundation

limitata nel tempo e in caso di accesso a basi


dati svolgono per lo più attività atomiche.
• Human Workflow: sono flussi funziona-
li che richiedono l’interazione con uno o più
utenti. Generalmente sono molto variabili nel
loro flusso, in funzione delle azioni eseguite
dagli utenti. Hanno una durata eventualmente
anche estesa nel tempo e se coinvolgono delle
basi di dati possono avere l’esigenza di gesti-
re long-running transaction e attività di com-
pensazione in caso di annullamento. Sono ad
esempio processi di approvazione documen-
tale e di gestione/istruttoria di pratica di la-
voro.

Con WF possiamo descrivere entrambe le Figura 3 Un esempio di Sequential Workflow


casistiche di flussi.

• I Workflow sono realizzabili dichiaran-


WinFx funzionerà anche su do direttamente del codice, oppure in modo
decisamente più comodo sfruttando appositi
Windows XP Service Pack Visual Designer. Esiste ad esempio un’esten-
2 e su Windows Server sione di Visual Studio 2005 per disegnare i
flussi di WF. Anche altri prodotti di Microsoft
2003 offrono dei designer alternativi e che non ri-
chiedono la presenza di Visual Studio 2005.
Ad esempio 2007 Microsoft Office system pre-
Architettura di WF vede un designer semplificato di workflow al-
Dal punto di vista architetturale (Figura 1) l’interno di SharePoint Designer 2007, l’evo-
WF è pensato per essere estremamente esten- luzione dell’attuale FrontPage.
dibile e personalizzabile, come tutto .NET 3.0. • Una volta definito un Workflow come
Dal punto di vista di WF un workflow è co- insieme di Activity, utilizzando un Visual De-
stituito da: signer, abbiamo bisogno di un Host che, come
• Un insieme di Activity, che sono da dice il termine, ospiti il Workflow e lo alimen-
pensare come i singoli mattoncini su cui si ti con eventuali parametri e/o eventi.
fonda un workflow. Le Activity sono i singo- • L’Host che ospita il Workflow si appog-
li passi di un flusso. Possono essere sia delle gia ad un motore di esecuzione (Runtime En-
Activity scelte nel set di attività di base (Base gine) che altro non è se non una classe .NET,
Activity Library), di alcune delle quali parle- di nome WorkflowRuntime, che si preoccupa
remo meglio più avanti in questo articolo, sia di caricare in memoria i Workflow, eseguen-
delle attività custom, create da noi o da terze doli e gestendone lo stato e la persistenza.
parti, arricchendo di funzionalità l’infrastrut- • Il WorkflowRuntime si appoggia a dei
tura di base di WF. servizi infrastrutturali di base (Runtime Ser-
• Le Activity sono definite all’interno vice), personalizzabili ed estendibili secondo
di un Workflow, che è una tipologia partico- le regole di sviluppo OOP. I Runtime Servi-
lare di Activity, in grado di contenerne altre ce consentono di arricchire di funzionalità il
e che può essere eseguito direttamente. Runtime, offrendo servizi di persistenza, ge-

N. 70 - Luglio/Agosto 2006 VBJ 13


Windows Workflow Foundation

stione dello stato, tracking, comunicazione da una classe base definita del framework di
con l’esterno, ecc. classi di WF e che si chiama System.Workflo
w.ComponentModel.Activity.

Vediamo lo scopo di alcune tra le principali


Un Workflow è un insieme Activity del motore di base di WF:
di Activity eseguite in un • Code: esegue del codice .NET. Si trat-
ta sicuramente dell’Activity più intuitiva per
host che si appoggia al chi è abituato a scrivere codice. Il rischio del-
WorkflowRuntime la CodeActivity è di creare un Workflow che
poi non è altro che un insieme di poche Co-
deActivity, che alla fine riproducono esatta-
mente il comportamento di un’applicazione
Workflow e Activity di base che si poteva tranquillamente scrivere senza
Per iniziare ad utilizzare WF è necessario sca- WF. Conviene pensare a questa Activity come
ricare .NET 3.0 [2] e installarlo insieme alle ad un punto di contatto con il mondo “code-
estensioni per Visual Studio 2005. Possiamo oriented” da utilizzare con parsimonia. Piut-
definire un nuovo progetto di tipo Workflow tosto se abbiamo porzioni di codice da esegui-
(Figura 2), ad esempio un Sequential Work- re in modo ripetitivo nei nostri flussi, convie-
flow, vedremo poi le tipologie di Workflow ne crearsi delle Activity custom e inserire al
definibili. A questo punto troviamo a nostra loro interno il codice, oppurtunamente para-
disposizione un designer grafico nel qua- metrizzato.
le possiamo trascinare, dalla Toolbox di Vi- • Delay: come dice il nome, una DelayAc-
sual Studio 2005, le singole Activity come se tivity sospende il flusso per un tempo impo-
fossero dei controlli di una form. Ogni Acti- stabile.
vity è descritta da una specifica simbologia • IfElse: rappresenta un costrutto If ...
grafica, sia nella Toolbox che poi nel grafo Then ... Else all’interno del flusso e permette
del Workflow (Figura 3). Il risultato di que- di eseguire delle valutazioni e delle scelte nel
sto drag’n’drop di Activity all’interno del no- percorso del flusso.
stro flusso sarà una classe .NET della quale • InvokeWebService: consente di invoca-
potremo personalizzare il comportamento e re un WebService (SOAP + HTTP) ester-
le funzionalità. Un Workflow può anche es- no, gestendone poi l’input, l’output ed even-
sere definito con un file XML, la cui esten- tuali Fault con le relative Activity (WebSer-
sione per WF è XOML. Un file XOML descri- viceInput, WebServiceOutput, WebService-
ve la serializzazione di un oggetto Workflow. Fault).
Il vantaggio di poter definire anche dei file • InvokeWorkflow: permette di avviare un
XOML e non solo classi di codice, al di là che Workflow esterno, con la possibilità di attiva-
siano state realizzate con il designer grafico o re processi asincroni.
meno, è che all’occorrenza possiamo pensare • Sequence: esegue una sequenza di al-
di creare dei nostri designer che producano tre Activity.
i Workflow in formato XOML, per poi compi- • Parallel: parallelizza delle attività o se-
larli con un apposito compilatore (WFC.EXE quenze di Activity.
= Workflow Compiler). • Replicator: permette di definire un bloc-
co di flusso che sarà poi eseguito N volte, dove
Come abbiamo già visto, le Activity sono le N dipende da come, caso per caso, andremo ad
unità minime di un Workflow. Nella pratica alimentare il flusso. Si pensi ad un processo
un’Activity non è altro che una classe .NET di approvazione con firme multiple. Il concet-
che deriva, direttamente o indirettamente, to di approvazione tramite firma sarà descrit-

14 VBJ N. 70 - Liglio/Agosto 2006


Windows Workflow Foundation

e dei contenuti di Sharepoint.

Tipologie di Workflow in WF
In Workflow Foundation sono definibili due
tipologie di Workflow: Sequential Workflow e
State Machine Workflow.

I Sequential Workflow (Figura 3) si utilizza-


no per descrivere flussi che sono costituiti da
una sequenza nota di Activity. Di solito un Se-
quential Workflow è temporalmente definito
e limitato. Spesso si utilizzano per rappresen-
tare dei System Workflow, in quanto le inte-
razioni tra sistemi sono generalmente note e
definite a priori, così come le eventuali varian-
ti nel flusso. Il più delle volte non richiedono
Figura 4 Un esempio di State Machine Workflow
interazioni con l’utente, anche se non possia-
mo escluderlo in modo assoluto. Da un punto
di vista operativo sono la tipologia più sempli-
ce di Workflow, in quanto prevedono solo la
to all’interno del Replicator, poi il numero di definizione della sequenza logica di Activity
firme necessarie sarà un dettaglio di ciascu- e di condizioni per attivarle. Per contro sono
na particolare istanza del flusso. Per ciascun flussi poco versatili e poco adatti a subire va-
firmatario sarà eseguito il flusso previsto dal riazioni eccessive di comportamento.
Replicator.
• While: dal nome si evince che si tratta Gli State Machine Workflow (Figura 4) sono
di un costrutto iterativo in base ad una con- invece pensati secondo l’idea di macchina a
dizione, esattamente come un Do ...While. stati finiti, che probabilmente molti di noi co-
• CallExternalMethod: invoca un metodo noscono anche solo per averla studiato all’uni-
dell’ambiente di hosting. È utilizzato per con- versità. In sostanza descrivono quei flussi in
sentire al Workflow di chiamare il suo Host, cui non è semplice definire un percorso lo-
eventualmente passandogli delle informazio- gico sequenziale ed è invece più immediato
ni. pensare ai possibili stati in cui si può trovare
• HandleExternalEvent: si tratta di un’atti- il “sistema”. Rifacendoci ad un esempio uni-
vità complementare a quella precedente. Pre- versalmente comprensibile, dovendo descri-
vede la possibilità di sospendere il flusso in vere un flusso di gestione ordini, potremmo
attesa che l’host invochi un evento per sbloc- trovarci nei seguenti stati:
carlo e passargli eventualmente delle infor-
mazioni che gli consentano di proseguire nel • Ordine inserito
processo. • Ordine in verifica al reparto vendite
• Ordine in backorder, perché manca
Vi sono altre Activity di base, che per ora merce a magazzino
non vedremo, così come esistono già diverse • Ordine evaso
Activity personalizzate, scaricabili da Internet • Ordine consegnato
[3]. Anche prodotti Microsoft come 2007 Mi- • Ordine annullato
crosoft Office system e Office SharePoint Ser- • Ordine completato
ver 2007 prevedono delle librerie di Activity
personalizzate per la gestione dei documenti Questi sono solo alcuni dei possibili stati di

N. 70 - Luglio/Agosto 2006 VBJ 15


Windows Workflow Foundation

un processo di gestione di un ordine, proba- sere un qualsiasi software in grado di suppor-


bilmente non sono i soli. Un processo che de- tare il runtime di .NET Framework. Potrebbe
scriva la gestione di un ordine dovrebbe po- ad esempio essere un’applicazione Windows
terli gestire tutti, pensando anche al fatto che Forms, un sito web ASP.NET, un portale Sha-
possiamo seguire diverse strade per arrivare repoint, un’estensione di Microsoft Office, un
agli stessi stati. Ad esempio “Ordine inserito” servizio del sistema operativo, ecc. In que-
è sicuramente lo stato iniziale, così come “Or- sto articolo introduttivo ho volutamente evi-
dine completato” è sicuramente lo stato con- tato di soffermarmi sui dettagli del codice, in
clusivo. Tra questi due stati potremmo però quanto ho preferito trasmettere l’idea e la lo-
avere una verifica del reparto vendite che, a gica alla base di WF. Per vedere un esempio
fronte di uno scoperto di fido del cliente, ci di base di codice di un Host è però sufficien-
porti nello stato di “Ordine annullato” per poi te creare un template di progetto Sequential
considerare chiuso l’ordine (“Ordine Comple- Workflow Console Application da Visual Stu-
tato”). Oppure qualora manchi giacenza a ma- dio 2005 e visualizzare il codice di avvio del-
gazzino potremmo portarci nello stato “Ordi- l’applicazione:
ne in backorder”, mentre in caso di disponi-
C# - .NET 3.0
bilità di merce potremmo evaderlo (“Ordine
evaso”), quindi consegnarlo (“Ordine conse- using(WorkflowRuntime workflowRuntime =
gnato”) e infine considerarlo concluso (“Ordi- new WorkflowRuntime())
ne completato”). D’altra parte però, se anche {
dovessimo trovarci in “Ordine in backorder”, AutoResetEvent waitHandle = new AutoResetEvent(false);
poi andremmo comunque in “Ordine evaso” workflowRuntime.WorkflowCompleted +=
non appena la merce fosse arrivata a magazzi- delegate(object sender, WorkflowCompletedEventArgs e)
no. Potremmo discutere ore dei possibili stati {waitHandle.Set();};
di un ordine. Il messaggio che voglio trasmet- workflowRuntime.WorkflowTerminated +=
tere è che un flusso di questo tipo è molto va- delegate(object sender, WorkflowTerminatedEventArgs e)
riabile nel suo comportamento, ma è certo ri- {
spetto a quelli che sono i suoi possibili stati. Console.WriteLine(e.Exception.Message);
Ecco quindi che uno State Machine Workflow waitHandle.Set();
si prefigge di descrivere flussi di questo tipo, };
che probabilmente sarebbero eccessivamen-
te articolati per poter essere incasellati in un WorkflowInstance instance =
Sequential Workflow. workflowRuntime.CreateWorkflow(typeof
Generalmente uno State Machine Workflow (WorkflowConsoleApplication1.Workflow1));
è guidato da eventi esterni, spesso scatenati instance.Start();
da interattività con utenti (Human Workflow).
Sono di solito processi duraturi nel tempo e waitHandle.WaitOne();
possono richiedere long-running transactions, }
con le relative compensation in caso di falli-
mento, qualora richiedano attività di modifica Come si può notare, è sufficiente istanziare
su basi dati e risorse esterne in genere. la classe WorkflowRuntime, per poi chieder-
le di creare una WorkflowInstance, a partire
Hosting e Runtime Service da un Workflow, definito con gli strumenti a
Come abbiamo già detto relativamente al- nostra disposizione, per poi avviarla. L’istan-
l’architettura di WF, i Workflow devono esse- za di WorkflowRuntime potrà anche essere
re ospitati da un’applicazione Host ed eseguiti configurata ed estesa nel suo comportamen-
nel WorkflowRuntime, che si appoggia a dei to, aggiungendo dei WorkflowRuntimeServi-
Runtime Service. L’applicazione Host può es- ce. Si tratta di oggetti in grado di fornire ser-

16 VBJ N. 70 - Liglio/Agosto 2006


Windows Workflow Foundation

vizi infrastrutturali al contorno del motore di per lavorare con i dati, per gestire scambi di
WF. Ad esempio se abbiamo l’esigenza di per- record da una sorgente ad una destinazione.
sistere lo stato di un Workflow tra un’Activi- SSIS e BizTalk poi sono vere e proprie appli-
ty e l’altra, pensiamo ad una DelayActivity cazioni o servizi, che sono eseguite in un loro
o all’attesa di un evento, possiamo utilizzare contesto. WF invece è eseguibile all’interno
un WorkflowPersistenceService che si occu- di altre applicazioni, anche e principalmen-
perà di gestire il salvataggio dello stato del te nostre, per consentire a noi di descrivere i
flusso. In WF esiste già un SqlWorkflowPer- flussi operativi dei nostri processi.
sistenceService nativo, che salva lo stato in
SQL Server, per aumentare la scalabilità delle Microsoft .NET 3.0 ad oggi è in versione Beta
nostre soluzioni. Se invece dobbiamo traccia- 2 e l’ultima build disponibile alla data in cui
re i flussi, possiamo utilizzare un Tracking- scrivo questo articolo è di Maggio 2006. Ben-
Service, come ad esempio il SqlTrackingSer- ché in beta è però scaricabile dal sito di Mi-
vice. In generale esistono diversi servizi al crosoft [2] dedicato all’argomento. Inoltre sia
contorno e possiamo crearne anche di nostri, WCF che WF sono in versione GoLive, cioè
con l’obiettivo di supportare e arricchire il fra- possiamo utilizzarli in applicazioni reali, oltre
mework di base. che per ricerca e sviluppo interno. Consiglio
quindi di scaricare l’ultima build di .NET 3.0
e iniziare a valutare questo nuovo e interes-
sante framework che in parte rivoluzionerà il
La persistenza dello stato modo di scrivere le nostre applicazioni. È an-
dei Workflow è garantita che utile fare riferimento al sito specifico di
WF [3] per scaricare esempi, activity custom
da servizi personalizzabili e trovare contenuti di vario genere, utili ad
del WorkflowRuntime inquadrare meglio questa tecnologia.

Riferimenti
[1] Paolo Pialorsi – “WinFx: Windows
Communication Foundation”, VBJ n° 69
Conclusioni [2] http://www.netfx3.com/
Un quesito abbastanza diffuso, quando si [3] http://wf.netfx3.com/
parla di WF, è che in realtà, almeno in appa- [4] http://www.devleap.com/winfx/
renza, in casa Microsoft vi sono già servizi che
potrebbero sembrare potenziali concorrenti di
WF, come BizTalk Server e SQL Server Inte-
gration Services (SSIS). In realtà è sbagliato
pensarli come concorrenti di WF. BizTalk Ser-
ver è un servizio server pensato per gestire
soluzioni principalmente message oriented,
orientate all’integrazione tra applicazioni e si-
stemi gestionali/ERP e informativi in genere.
BizTalk descrive nell’Orchestration Designer
dei flussi sequenziali, infatti nella sua prossi-
ma versione dovrebbe appoggiarsi a WF per
farlo, ma questa è solo una minima parte del
lavoro che un BizTalk server può svolgere.
Anche SSIS non è un concorrente di WF, né
tantomeno di BizTalk, infatti SSIS è pensato

N. 70 - Luglio/Agosto 2006 VBJ 17


Tecniche

CAPermutations:
una libreria per
risolvere problemi
combinatori di Francesco Balena
Permutazioni

D a quando ho potuto mettere le mani su


un computer sono sempre stato affasci-
nato dai problemi combinatori. In prima appros-
risoluzione del famoso problema
delle regine (ovvero: come siste-
mare N regine su una scacchie-
simazione, un problema combinatorio prevede la ra N*N in modo che nessuna dia
scelta di una (o più) permutazioni o combinazioni scacco ad un’altra)
di N elementi in modo da soddisfare alcuni vinco- • Lo stesso vale per molti
li. È facile intuire che molti problemi si risolvono giochi di tipo enigmistico, come
solo grazie a tecniche combinatorie: ad esempio il Sodoku oppure le
parole crociate.
• La generazione di tutti gli anagrammi di • Il problema dello zaino:
una parola richiede la generazione di tutte le per- abbiamo N oggetti di peso o in-
mutazioni possibili dei suoi caratteri, per poi sce- gombro differenti da trasportare
gliere tra le parole ottenute quelle di senso com- in uno zaino che ha una capaci-
piuto tà (come peso o volume) massi-
• Un programma per generare sistemi di To- ma pari a un certo valore: quali
tocalcio, Lotto, Totip e simili richiedono la gene- oggetti scegliere in modo che la
razione di tutte le colonne possibili, da cui vengo- capacità dello zaino sia sfrutta-
no poi scelte quelle che soddisfano alcuni requisi- ta al massimo, in modo cioè che
ti (tipo numero minimo e massimo di segni, ecc.) la somma dei volumi o dei pesi
• Un programma per determinare l’orario sco- degli oggetti scelti sia la più vi-
lastico, oppure più in generale, per stabilire turni cina possibile (ma non superio-
di lavoro richiede di generare tutte le possibili as- re) alla capacità dello zaino? Se
segnazioni (persona,turno) per poi scegliere quel- pensate che invece di uno zaino
le che soddisfano i vincoli impostati dall’utente avete a che fare con un contai-
• Molti problemi matematici si basano sul- ner, vedete che il problema ha
la generazione di tutte le possibili permutazioni o delle implicazioni pratiche non
combinazioni di N elementi, ad esempio la genera- indifferenti
zione degli quadrati magici di ordine N oppure la • Il modo migliore per ta-

N. 70 - Luglio/Agosto 2006 VBJ 19


Tecniche

gliare sagome bidimensionali da una super-


ficie piana si determina provando i diversi Una delle cose più intriganti di un problema
modi di combinare le varie sagome in modo combinatorio è il fatto che anche problemi ab-
da minimizzare il materiale non utilizzato (si bastanza semplici richiedono spesso soluzio-
pensi ad esempio al problema di tagliare in ni complesse dal punto di vista computazio-
modo ottimale le pelli di una sedia o un di- nale, e soprattutto richiedono tanto tempo di
vano a partire dal pellame a disposizione ed CPU a meno di non ottimizzare al meglio l’al-
evitando i punti in cui il pellame non è uti- goritmo. Le possibili permutazioni di 10 og-
lizzabile o presenta imperfezioni) getti distinti è pari al fattoriale di 10, ovvero
• Il percorso ottimale per andare dalla 1*2*3*4*5*6*7*8*9*10 = 3.628.800. Disporre i
località A alla località B in trenoo aereo può numeri 1-16 su una griglia 4x4 per vedere qua-
essere risolto combinando i vari percorsi in- li combinazioni generano un quadrato magico
termedi, in modo da ridurre la distanza com- (ossia un quadrato in cui la somma lungo le
plessiva, il costo complessivo dei biglietti, il righe, colonne, e diagonali è costante) richie-
numero delle coincidenze aeree o ferroviarie, de l’analisi di 20mila miliardi di posizioni, e
oppure ancora il tempo speso aspettando tali così via. Per riuscire a risolvere questi proble-
coincidenze. (Pensate ad esempio a come pre- mi in tempi accettabili si richiede spesso di
notate un viaggio con Expedia.) ottimizzare il codice al massimo e di trovare
• La generazione di permutazioni e com- delle tecniche di “potatura” in modo da poter
binazioni è anche alla base di numerose tec- scartare interi gruppi di soluzioni prima di do-
niche di “attacco” per scardinare alcuni siste- verle analizzare una a una. Anche in questo
mi di sicurezza. Ad esempio, i programmi che modo, la risoluzione di un quadrato magico
tentano di trovare le password per un sito fun- di ordine 5 può richiedere alcuni giorni an-
zionano combinando le parole in un diziona- che sulle CPU più performanti. Per avere una
rio che contiene le parole e nomi propri più idea di quante varianti vi siano per questi pro-
comuni. blemi combinatorio, date una occhiata al sito
The Combinatorial Object Server [2].
Potrei continuare con altri esempi, ma credo
che sia chiaro il fatto che le tecniche combi- Ogni problema combinatorio è una storia a
natorie possono essere utili in moltissimi casi. sè stante, nel senso che il codice per trovare
Per saperne di più, non dovete fare altro che le soluzioni di uno schema di Sodoku è molto
gogglare un po’ su termini come “permuta- diverso dal codice per generare l’orario scola-
tions” o “combinations” e scoprirete un sac- stico ottimale o per trovare il tragitto aereo mi-
co di cose interessanti. gliore. D’altra parte, queste applicazioni han-
In questi anni ho scritto numerosi program- no anche molti tratti in comune. In particola-
mi che richiedevano la generazione di permu- re, la parte che genera le varie permutazioni
tazioni o combinazioni di elementi simili. For- o combinazioni di elementi è spesso simile.
se il primo programma di questo tipo è stato Non uguale, ma simile. Quello che cambia in
un generatore di sistemi per il totocalcio che ciascun caso sono le routine che controllano
girava su Sinclair Spectrum. Uno dei più re- se una combinazione è valida o meno, oppu-
centi è stato il Sodoku Solver [1] che risolve re le funzioni che procedono alla “potatura”
automaticamente gli schemi di Sodoku più degli alberi delle soluzioni. Alla fine ho pen-
complessi in qualche frazione di secondo, di- sato: perchè non estrapolare l’algoritmo di ge-
rettamente dal vostro broswer. Nei vent’anni nerazione delle combinazioni in modo da po-
intercorsi tra questi due programmi, ho usa- terlo riutilizzare in occasioni differenti? Il ri-
to tecniche combinatorie per ottimizzare la sultato è la libreria CAPermutations, ovvero
soluzione di alcuni problemi come quelli ci- l’oggetto di questo articolo.
tati sopra. La libreria in questione contiene solo una

20 VBJ N. 70 - Liglio/Agosto 2006


Tecniche

classe, Permutations, che però già in questa tuisce in un colpo solo tutte le pemutazioni.
prima versione è in grado di risolvere la mag- Poichè ogni permutazione è un vettore di tipo
gior parte dei problemi citati in precedenza. T (dove T è definito al momento di istanziare
Per i problemi non particolarmente comples- la classe generica Permutations), allora il ri-
si, utilizzare questa libreria è davvero sempli- sultato di questo metodo è un jagged array
ce: si crea una istanza della classe e si passa di tipo T, ovvero un vettore dove ciascun ele-
al costruttore un vettore contenente tutti gli mento è a sua volta un vettore di tipo T.
elementi da permutare, poi si entra in un ci-
clo For Each che permette di enumerare tut- ‘ VB
te le possibili permutazioni. La classe Permu- Dim results()() As Char = perms.GetAllPermutations()
tations usa i generics, in modo da accettare // C#
e restituire un array tipizzato contenente gli char[][] results = perms.GetAllPermutations();
elementi che devono essere (o che sono sta-
ti) combinati: La classe Permutations è anche in grado di
determinare le permutazioni di un gruppo di
‘ genera le permutazioni dei caratteri A,B,C,D K elementi presi dall’insieme di N elementi
Dim elements() As Char = {“A”c, “B”c, “C”c, “D”c} forniti in input, con K <= N . Per ottenere tali
Dim perms As New Permutations(Of Char)(elements) permutazioni basta passare al costruttore un
For Each chars() As Char In perms secondo argomento, pari al numero K di ele-
‘ crea e visualizza la stringa ottenuta menti che devono apparire nel risultato:
‘ concatenando i caratteri in the risultato
Console.Write(New String(chars) & “, “) ‘ genera le permutazioni dei due caratteri scelti tra
Next ‘ i caratteri A,B,C,D
Dim elements() As Char = {“A”c, “B”c, “C”c, “D”c}
Il codice C# è altrettanto semplice: Dim perms As New Permutations(Of Char)(elements, 2)
‘ .... per ciascun loop come prima
// genera le permutazioni dei caratteri A,B,C,D
char elements[] = {“A”c, “B”c, “C”c, “D”c};
Ecco il risultato generato dal ciclo:
Permutations<Char> permutations = New Permutations<Char>
AB, AC, AD, BA, BC, BD, CA, CB, CD, DA,
(elements);
DB, DC,
foreach ( char[] chars in perms )
{
// crea e visualizza la stringa ottenuta La classe Permutations permette di risolvere
// concatenando i caratteri del risultato una numerosa classe di problemi combinato-
Console.Write(new string(chars) + “, “); ri e statistici. Ad esempio, se A,B,C,D rappre-
} sentano 4 città, l‘insieme delle permutazioni
rappresentano tutti i possibili percorsi che le
Ecco il risultato che appare nella finestra di uniscono e che non ripassano mai da una di
console, ovvero tutte le possibili permutazioni esse: un programma può facilmente analiz-
degli N elementi forniti in input: zare questi percorsi per trovare quello che
richiede meno tempo o ha un costo minore.
ABCD, ABDC, ACBD, ACDB, ADBC, ADCB, BACD, Se invece gli elementi rappresentano possi-
BADC, BCAD, BCDA, BDAC, BDCA, CABD, CADB, bili azioni – ad esempio, l’azione di sistemare
CBAD, CBDA, CDAB, CDBA, DABC, DACB, DBAC,
una pedina su una determinata casella delle
DBCA, DCAB, DCBA,
scacchiera – allora l’insieme delle permuta-
zioni permette di stabilire quale sequenza di
Invece di un loop For Each potete anche usa- azioni tra quelle possibili permette di ottenere
re il metodo GetAllPermutations, che resti- il risultato migliore (ad esempio, vincere una

N. 70 - Luglio/Agosto 2006 VBJ 21


Tecniche

partita di tris). È importante notare che il ri-


sultato non conterrà due elementi uguali, il Ed ecco il risultato che appare nella conso-
che è corretto perchè non vogliamo visitare le window.
due volte la stessa città e non possiamo siste-
mare due pedine nella stessa casella. Giuseppe - Francesco
Giuseppe - Marco
Giuseppe - Piero
La classe Permutations permette anche di
Giuseppe - Gianni
generare le combinazioni di K oggetti pre- Giuseppe - MariaTeresa
si da un universo di N oggetti, come al solito Francesco - Marco
con K <= N. L’unica differenza tra permuta- Francesco - Piero
zioni e combinazioni è che con queste ulti- Francesco - Gianni
me l’ordine è ininfluente, quindi ad esempio Francesco - MariaTeresa
la soluzione ABC è considerata equivalente a Marco - Piero
ACB, BAC, BCA, CAB, e CBA perchè quello Marco - Gianni
Marco - MariaTeresa
che conta sono gli elementi che compaiono
Piero - Gianni
nel risultato e non il loro ordine. Le combina- Piero - MariaTeresa
zioni permettono di risolvere tipi di problemi Gianni – MariaTeresa
differenti da quelli visti finora. Per esempio,
le combinazioni degli elementi {Giuseppe,Fra
ncesco,Marco,Piero,Gianni,MariaTeresa} con Fin qui niente di particolarmente eccitan-
K=2 potrebbero servire per generare il calen- te, visto che è facile ottenere lo stesso risul-
dario della prima serie di partite di un torneo tato con qualche ciclo innestato di C# o VB,
di tennis a cui partecipano sei membri del soprattutto se i valori di K e N sono costanti.
team di Code Architects, in modo che ciascu- Con K o N variabili occorre prevedere degli
na persona si batta una volta contro tutte le array che gestiscono gli indici dei vari loop,
altre. In questo caso occorre usare le combi- ma è un codice alla portata di tutti.
nazioni perchè non occorre disputare la par- Le cose cominciano a diventare interessan-
tita Francesco-Giuseppe se si è già giocata la ti quando l’insieme degli elementi contiene
partita Giuseppe-Francesco. (In altre parole, elementi uguali, che non possono quindi es-
l’ordine degli elementi è ininfluente.) sere considerati distinti quando si generano
le permutazioni o le combinazioni. L’esempio
Per generare combinazioni anzichè permu- classico è la generazione di anagrammi: il nu-
tazioni, è sufficiente passare un valore enu- mero totale di anagrammi della parola “case”
merativo PermutationKind come terzo ar- è 23, dato dal numero di pemutazioni possi-
gomento al costruttore della classe Permu- bili di 4 lettere (=1*2*3*4) meno uno per evi-
tations. Ecco ad esempio come generare le tare di conteggiare la parola originale. D’al-
partite del torneo: tra parte, il numero di anagrammi della pa-
rola “casa” è soltanto 11, perchè la parola ori-
Dim elements() As String = {“Giuseppe”, “Francesco”, ginale contiene due lettere uguali e quindi il
“Marco”, “Piero”, “Gianni”, “MariaTeresa”} numero di permutazioni distinte che è pos-
Dim perms As New Permutations(Of String)(elements, 2, _ sibile creare è pari a 12, non 24. Questo par-
PermutationKind.Combination ) ticolare inizia a complicare non poco la strut-
‘ anzichè PermutationKind.Permutations tura di un programma C# o VB che risolve
For Each elem() As String In perms il problema specifico, ma la classe Permuta-
‘ ciascun elemento del risultato è un array tions rimuove automaticamente le ripetizio-
‘ con due elementi ni dal risultato (Figura 1).
Console.WriteLine(“{0} - {1}”, elem(0), elem(1))
Next Ecco il codice nell’evento Click nel pulsante

22 VBJ N. 70 - Liglio/Agosto 2006


Tecniche

tato occorre specificare un valore maggiore di


1 come quarto argomento del costruttore del-
la classe Permutations:

‘ ricava le possibili permutazioni di due dadi


Dim elements() As Integer = {1, 2, 3, 4, 5, 6}
‘ passiamo 2 come quarto argomento potendo accettare
‘ che lo stesso valore appaia due volte
Dim perms As New Permutations(Of Integer)(elements, 2, _
PermutationKind.Permutations , 2)
For Each dice() As Integer In perms
Console.WriteLine(“{0} {1}”, dice(0), dice(1))
Next

In una prima versione della libreria avevo


Figura 1 Il generatore di anagrammi in azione
usato un booleano per indicare se le ripetizio-
ni erano ammesse o meno, ma usare un inte-
ro ha il vantaggio di permettere una maggiore
“Show anagrams” del programma demo: flessibilità. Ad esempio, è possibile generare
tutte le permutazioni di tre dadi in cui lo stes-
‘ si prepara a generare le permutazioni dei caratteri so valore compare al massimo due volte:
‘ della parola
Dim chars() As Char = txtWords.Text.ToCharArray() Dim perms As New Permutations(Of Integer)(elements, 3, _
Dim permutations As New Permutations(Of Char)(chars) PermutationKind.Permutations, 2)
lstAnagrams.Items.Clear()
For Each chrs() As Char In permutations Criteri di selezione
Dim anagram As String = New String(chrs)
‘ nel risultato non include la parola originale La feature più potente della libreria CAPer-
If anagram <> txtWords.Text Then _ mutations è la possibilità di impostare dei cri-
lstAnagrams.Items.Add(anagram) teri di selezione delle varie permutazioni. In
Next pratica, è possibile fornire alla libreria l’indi-
lblMessage.Text = String.Format(“Found {0} anagrams”, _ rizzo di un metodo di callback: questo meto-
lstAnagrams.Items.Count) do viene chiamato mentre viene generata una
nuova permutazione, e quindi il programma
Come ho fatto notare prima, nella maggior client ha la possibilità di scartare le permu-
parte dei casi quando chiediamo le permuta- tazioni che non interessano. La cosa interes-
zioni o combinazioni di un gruppo di elementi sante è che la routine di callback viene chia-
non vogliamo che lo stesso elemento compaia mata non soltanto quando la permutazione
più volte. Ad esempio, se un elemento rappre- è stata completata, ma anche durante le fasi
senta la posizione di una regina posta sulla intermedie. Supponiamo ad esempio di voler
scacchiera, l’elemento non può comparire più calcolare le permutazioni dei numeri 1-9 ma
di una volta perchè una casella non può con- con la condizione che il numero N non si tro-
tenere più pezzi. Altri problemi combinato- vi in posizione N-esima. Ovviamente possia-
ri però non hanno questa limitazione. Se ad mo generare le 9! permutazioni dei numeri in
esempio stiamo calcolando tutte le possibili questione e poi scartare quelli che non soddi-
permutazioni di due dadi, dovremo includere sfano la condizione, ma il metodo di callback
anche i risultati in cui vi sia un doppio uno, permette di accelerare notevolmente i tempi
un doppio due, ecc. Per ottenere questo risul- di elaborazione: infatti non ha senso prova-

N. 70 - Luglio/Agosto 2006 VBJ 23


Tecniche

re per poi scartare i milioni di permutazioni


che presentano la cifra 1 al primo posto, ma
è molto più efficiente dire “non farlo!” nel
momento il cui la classe Permutations prova
a generare la prima permutazione errata, di-
cendole in pratica di saltare tutte le permu-
tazioni di quel tipo.
Ecco un programma Visual Basic che
risolve il problema delle permutazioni di
questo tipo:

Sub GeneratePermutations()
‘ genera le permutazioni delle cifre 1-5
Dim elements() As Integer = {1, 2, 3, 4, 5}
Dim permutations As New Permutations(Of Integer) _
Figura 2 Ricerca delle soluzioni per il problema delle
(elements, 5, PermutationKind.Permutations, 1, _ regine (e delle amazzoni)
AddressOf PermutationFilter)
For Each perm() As Integer In permutations
Dim sb As New System.Text.StringBuilder è stato appena aggiunto prima di chiamare il
For Each n As Integer In perm metodo di callback. Il terzo argomento è Fal-
sb.Append(n) se se la permutazione è stata costruita, True
Next se siamo in fase di backtrack (vedi dopo). Il
Console.WriteLine(sb.ToString) metodo deve restituire PermutationResult.P
Next roceed se la permutazione può essere accet-
End Sub tata, Permutation-Result.Backtrack se deve
essere scartata.
Private Function PermutationFilter( _ La possibilità di effettuare backtracking, ov-
ByVal permutation() As Integer, _ vero di tornare indietro sui propri passi se il
ByVal level As Integer, _ metodo di callback restituisce PermutationRe
ByVal backtracking As Boolean) As PermutationResult sult.Backtrack, aumenta enormemente il po-
‘ l’elemento appena aggiunto tenziale della libreria e le permette di risol-
Dim number As Integer = permutation(level) vere problemi combinatori molto complessi.
‘ esegue il backtracking se l’elemento non è Ecco ad esempio una classe che risolve il fa-
‘ uguale alla sua posizione moso problema delle regine, ovvero come si-
If number <> (level + 1) Then stemare N regine su una scacchiera N*N in
Return PermutationResult.Proceed modo che non si diano scacco a vicenda. Si
Else tratta di un classico problema combinatorio
Return PermutationResult.Backtrack su cui, prima dell’avvento dei computer, si
End Function sono arrovellati dei geni come Gauss e altri
famosi matematici.
La procedura di callback, detta anche proce- Questo problema corrisponde a trovare una
dura di filtro, accetta tre argomenti e restitui- permutazione dei numeri 1-N, dove ogni ele-
sce un enumerativo PermutationResult. Il pri- mento P(n) della permutazione rappresenta
mo argomento è il vettore che rappresenta la la colonna in cui posizionare la regina della
permutazione che è stata costruita fino a quel riga N. Il solo fatto di richiedere permutazio-
momento; il secondo argomento rappresenta ni delle cifre 1-N (dove ogni elemento della
il livello di costruzione della permutazione, permutazioni può apparire una sola volta) as-
ovvero l’indice zero-based dell’elemento che sicura che le regine si trovino su colonne ol-

24 VBJ N. 70 - Liglio/Agosto 2006


Tecniche

tre che su righe separate. Di fatto quindi, il


metodo di callback deve soltanto tenere trac- Ho preparato un programma che permette
cia di quali diagonali (principali e secondarie, di risolvere il problema delle regine e delle
ovvero quelle in direzione NO-SE e quelle in amazzoni con N compreso tra 4 e 20 (Figura
direzione NE-SO) sono occupate dalle regine 2). In aggiunta alle feature appena descritte,
poste sulla scacchiera fino a quel momento. il programma è anche in grado di scartare le
Nel Listato 1 è riportato il codice C# di una riflessioni e le rotazioni, per ottenere quelle
classe che calcola tutte le soluzioni del pro- che si definiscono le soluzioni base del pro-
blema, con N qualsiasi. blema. Grazie alla classe Permutations, con
Poichè la procedura di filtro deve gestire gli una manciata di istruzioni è stato possibile
array di booleani mainDiags e secDiags (che risolvere un problema combinatorio davvero
contengono true se la diagonale corrispondente complesso. E il tutto in modo super-efficien-
è stata già occupata), la stessa routine deve te: sul mio computer il problema delle regine
anche rimettere i valori a false quando – in di ordine 12 è risolto in circa 1.5 secondi, per
fase di backtracking – la regina viene rimossa trovare tutte le 1787 soluzioni base.
da quella posizione per tentare un’altra
strada. Ecco allora che si spiegano le seguenti Al solito, il sorgente del programma è alle-
istruzioni :
gato all’articolo.
Una ultima, importante nota: questa
// se backtracking, aggiorna i valori e ritorna versione della libreria CAPermutations
if ( backtracking ) è disponibile come DLL compilata e
{ può essere usata esclusivamente nei
mainDiags[mainDiag] = false; programmi freeware o no-profit. Se avete
secDiags[secDiag] = false; dubbi su questa forma di licenza o se avete
return PermutationResult.Backtrack; la necessità di utilizzarla in applicazioni
} commerciali, contattatemi via email.

Con qualche piccola aggiunta alla Riferimenti


procedura di callback è anche possibile
risolvere il problema delle amazzoni (o [1] http://www.dotnet2themax.it/sodoku/
delle super-regine) dove una amazzone è default.aspx
una regina con super-poteri che è anche in [2] http://www.theory.cs.uvic.ca/~cos/
grado di muoversi come un cavallo. Queste root.html
sono le sole righe che occorre aggiungere
nel punto segnato da un commento nel
listato della classe:

// ulteriori test per il problema delle amazzoni


if ( Kind == ProblemKind.Amazons )
{
// controlla le celle della riga precedente
if ( row > 0 && ( columns[row - 1] == col - 2
|| columns[row - 1] == col + 2 ) )
return PermutationResult.Backtrack;
// controlla le celle di due righe prima
if ( row > 1 && ( columns[row - 2] == col - 1
|| columns[row - 2] == col + 1 ) )
return PermutationResult.Backtrack;
}

N. 70 - Luglio/Agosto 2006 VBJ 25


Tecniche

Listato 1 Il codice per il problema delle regine

using System; (numbers, Side,


using System.Collections; PermutationKind.Permutations, 1,
using System.Collections.Generic; Filter);
}
namespace CodeArchitects
{ // il metodo filtro viene invocato quando
public class Queens : IEnumerable // viene aggiunta o rimossa una nuova
{ // regina dalla scacchiera
// campi di input
public readonly int Side; PermutationResult Filter(int[] columns,
// campi utilizzati dal metodo filtro int row, bool backtracking)
bool[] mainDiags; {
bool[] secDiags; // la colonna della regina appena
// aggiunta alla riga
// costruttore int col = columns[row];
// le diagonali utilizzate
public Queens(int side) // da questa regina
{ int mainDiag = row - col + Side;
this.Side = side; int secDiag = row + col;
} // se backtracking, aggiorna
// i valori e ritorna
// il metodo enumeratore delega if ( backtracking )
// all’enumeratore della classe {
// Permutations mainDiags[mainDiag] = false;
secDiags[secDiag] = false;
public IEnumerator GetEnumerator() return PermutationResult.Backtrack;
{ }
Permutations<int> permutations =
CreatePermutationObject(); // controlla se le diagonali sono
return permutations.GetEnumerator(); // già occupate da un’ulteriore regina
} if ( mainDiags[mainDiag] ||
secDiags[secDiag] )
// metodo di supporto che inizializza return PermutationResult.Backtrack;
// e restituisce un oggetto Permutations
// da utilizzare per l’enumerazione dei // ( ... aggiungere qui il codice del
// quedrati // problema delle amazzoni)
// se arriva qui, contrassegna le
private Permutations<int> // diagonali come “prese”
CreatePermutationObject() mainDiags[mainDiag] = true;
{ secDiags[secDiag] = true;
// inizializza il vettore permutazione // segnala che la nuova
// con numeri nell’intervallo 1-N // permutazione è ok
int[] numbers = new int[Side]; return PermutationResult.Proceed;
for ( int i = 0; i < Side; i++ ) }
numbers[i] = i; }
// inizializza i campi utilizzati dal }
// metodo filtro
mainDiags = new bool[Side * 2 + 1];
secDiags = new bool[Side * 2 + 1];
// crea e restituisce
// l’oggetto Permutations
return new Permutations<int>

26 VBJ N. 70 - Liglio/Agosto 2006


APPLICATIVI

.NET Sql
Authorization Manager
(NetSqlAzMan)
Il nome è pittoresco ma non si tratta né di un super-eroe,
né di un dentifricio raccomandato dai migliori dentisti
italiani. È un gestore di autorizzazioni per applicazioni
sviluppate con il .NET Framework 2.0 (smart-client/
web). NetSqlAzMan

di Andrea Ferendeles

ceforge.net.

N
etSqlAzMan è rivolto a tutti gli svi-
luppatori Microsoft .NET 2.0 che ne- Sicurezza nelle
cessitano di gestire autorizzazioni ap- applicazioni
plicative loosely-coupled, cioè debolmente ac- Quando si parla di sicurezza
coppiate con il codice sorgente, in modo velo- applicativa è possibile in gene-
ce e snello avendo queste autorizzazioni sem- re scrivere simbolicamente la se-
pre a disposizione in un database relazionale guente equazione:
come MS Sql Server (2000/MSDE/2005/Express).
Chi di voi già conosce MS Authorization Manager { Sicurezza } = { Autenticazione }
(AzMan) oppure ADAM (Active Directory Applica- + { Autorizzazione }
tion Mode) allora è nel posto giusto… ma aspetta-
tevi tante novità. dove per Autenticazione si in-
tende la fase di verifica delle cre-
NetSqlAzMan è un progetto open source ed denziali (chi sei?) e per Autoriz-
è ospitato dalla community SourceForge.net. zazione, il momento in cui, ac-
Da questo link è possibile scaricare sia i sorgen- certata l’identità dell’utente, si
ti (C#.net) sia il pacchetto di installazione (.MSI) guarda a cosa questo utente può
per la piattaforma Win32: http://netsqlazman.sour- o non può fare. In genere la fase
di autenticazione avviene prima
Andrea Ferendeles, si occupa da diversi anni di sviluppo, di tutte ed è sufficiente accerta-
progettazione software e basi dati su tecnologia Microsoft. re una sola volta le credenziali
È attualmente alle dipendenze della società Eidos Sistemi di
Formazione e collabora con Microsoft Italia per la gestione del dell’utente senza poi ogni volta
Microsoft eGovernment Competence Center per la Pubblica (a run-time) ripetere tale opera-
Amministrazione. Ha partecipato come speaker a conferenze zione (pensiamo al momento del
tecniche come TeckTalk 2004 tenendo sessioni su tematiche
“logon” sul nostro PC).
legate all’accesso dati avanzato con Sql Server e .NET e alla
realizzazione di servizi Windows con .NET. È certificato MCT, La seconda fase dà per scontato
MSF, MCSD e MCDBA. Può essere contattato tramite e-mail che qualcuno abbia già procedu-
all’indirizzo ferendeles.andrea@fastwebnet.it. to alla verifica delle credenziali e

N. 70 - Luglio/Agosto 2006 VBJ 27


APPLICATIVI

che quindi l’identità dell’utente sia “accerta- ed alcuni “Ruoli Applicativi” ovvero gruppi
ta” e “nota”. A questo punto, di fronte alla ri- di persone che nell’Applicazione posso com-
chiesta dell’utente di una applicazione, di ese- piere le medesime operazioni. Supponiamo
guire una determinata operazione, il sistema che l’applicazione che stiamo scrivendo deb-
di Autorizzazioni fornisce una risposta, prele- ba avere funzioni di gestione della contabilità
vando tutte le informazioni necessarie a pren- aziendale, del magazzino e così via, insomma
dere tale decisione da una qualche fonte dati il classico gestionale.
(ad esempio le ACL del File System).
L’applicazione dovrà operare delle distinzioni
Volendo a tutti costi fare un esempio, basta e permettere determinate operazioni ad utenti
pensare a quando ci rechiamo in aeroporto ben specificati, mentre ad altri le stesse ope-
per prendere un aereo. razioni dovranno essere negate. Per esempio
Quando ci presentiamo al Check-In, ci vie- consideriamo l’operazione “visualizza - bilan-
ne chiesto biglietto aereo e documento d’iden- cio di fine anno” che riporta in dettaglio i co-
tità e ci viene rilasciato un “ticket” di sicu- sti ed i ricavi di un anno di attività. È ragione-
rezza che è costituito dalla “carta d’imbarco” vole dire che tale operazione deve esser con-
(Autenticazione). A questo punto, e solo dopo cessa solo all’amministratore dell’azienda e al
aver ritirato la carta d’imbarco, possiamo re- più ai suoi dirigenti, ma sicuramente non agli
carci all’uscita preposta per il nostro volo. Al- impiegati. È inoltre ragionevole pensare che
l’interno della zona d’imbarco però, non sare- spesso l’amministratore od uno dei suoi diri-
mo “autorizzati” a prendere un volo qualsia- genti, per pura pigrizia o mancanza di tempo,
si ma solo ed esclusivamente il volo indicato vogliano “delegare” questa operazione ad una
nella carta d’imbarco stessa; tale controllo si segretaria, ovvero concederle (magari tempo-
esaurisce al momento dell’imbarco (Autoriz- raneamente) il permesso di compiere tale ope-
zazione) e solo dietro presentazione del “tic- razione in loro vece.
ket” rilasciato durante il check-in. Mi scuso
se l’esempio è risultato banale ma è bene fare Ora, come si può realizzare un’applicazione
chiarezza, almeno in questo contesto, per ca- del genere, senza “cablare” nel codice istru-
pire esattamente in quale contesto NetSqlAz- zioni del tipo:
Man si colloca.
If (utente = “Mario” or utente = “Giuseppe”) then
Ed eccoci dunque al punto: NetSqlAzMan è (autorizzato)
proprio colui che conserverà e custodirà le au- Else
torizzazioni, dando risposta “si, sei autorizza- (non autorizzato)
to” oppure “no, non sei autorizzato” a chiun-
que ne faccia richiesta (le applicazioni). Net- In primo luogo dobbiamo cercare di astrarre
SqlAzMan si appoggia invece al sistema ope- il più possibile dal concetto di “singolo uten-
rativo MS Windows per espletare la fase di te” e passare invece al concetto di “gruppo di
autenticazione (Kerberos / NTLM). utenti” ovvero un insieme di utenti a cui que-
sta operazione verrà concessa. All’atto poi del
Cerchiamo ora di capire, con un esempio disegno fisico decideremo quali utenti appar-
concreto, il meccanismo delle autorizzazio- tengono a quale gruppo:
ni in un contesto applicativo. Immaginiamo
una applicazione gestionale di una Azienda If (utente appartiene al gruppo “Amministratori”) then
qualunque. All’interno di questa Azienda pos- (autorizzato)
siamo sicuramente identificare alcuni “Ruoli Else
Aziendali” come ad esempio: l’amministrato- (non autorizzato)
re, i dirigenti, le segretarie, gli impiegati, ecc.

28 VBJ N. 70 - Liglio/Agosto 2006


APPLICATIVI

Riquadro 1 Caratteristiche e differenze

Ms AzMan:
• È COM.
• È dotato di una console mmc 2.0 (COM).
• Il suo storage può essere un file Xml o ADAM (Active Directory Application Mode – è un LDAP).
• È role-based.
• Supporta gruppi applicativi statici/dinamici, members/non-members.
• Struttura formata da Roles  Tasks  Operations. (Roles e Tasks gerarchici, Operations no).
• Si possono dare autorizzazioni solo ai Ruoli.
• Non implementa il concetto di “delega”.
• Non gestisce le autorizzazioni “nel tempo”.
• Non scatena eventi.
• L’unico tipo di autorizzazione è “Allow” (per dire “deny” occorre rimuovere l’utente/gruppo dal Ruolo).
• Supporta Scripting / Biz rules.

NetSqlAzMan:
• È .NET 2.0.
• È dotato di una console mmc 3.0 (.NET).
• Il suo storage è un database Sql Server (2000/MSDE/2005/Express).
• È basato su tecnologia Tdo -Typed Data Object.
• È Item-based.
• Struttura formata da Roles  Tasks  Operations. (Tutti gerarchici).
• Si posso dare autorizzazioni a Ruoli, Task e Operazioni.
• Supporta gruppi applicativi statici/dinamici, members/non-members.
• Test delle query LDAP direttamente dalla console.
• È time-dependant.
• È delegate-compliant.
• Scatena eventi (ENS).
• Supporta 4 tipi di autorizzazione:
o Allow with delegation (autorizzato e autorizzato a delegare).
o Allow (autorizzato).
o Deny (non autorizzato).
o Neutral (permesso neutrale, dipende dai permessi degli Items di livello superiore).
• Autorizzazioni gerarchiche.
• Non supporta Scripting / Biz rules.

Così facendo però stiamo introducendo un te può fare o no quella determinata opera-
legame troppo forte tra i “gruppi” e ciò che i zione. L’unico elemento di collegamento tra
gruppi stessi “possono fare”. Cosa accadreb- l’applicazione e il repository delle autorizza-
be infatti se domani decidessimo di passare zioni, è il nome dell’operazione stessa. L’in-
di competenza una certa operazione da un sieme di tali nomi definisce “un contratto”
gruppo ad un altro? e, come tale, è vincolante; se si cambia o nel-
Proviamo allora ad operare un ulteriore pro- l’applicazione o nel repository anche il nome
cesso di disaccoppiamento e dire: di una sola operazione sarà necessario modi-
ficare l’altro/a di riflesso.
If (utente è autorizzato a compiere l’operazione X) then
(autorizzato) L’identificazione univoca dell’utente ci ver-
Else rà fornita dal sistema di Autenticazione (Win-
(non autorizzato) dows), mentre il sistema di Autorizzazioni do-
vrà rispondere “si” o “no” alla domanda “è au-
Siamo passati in questo modo a fare la cosa torizzato a compiere l’operazione X”?. È ne-
più semplice e naturale e cioè a chiederci, a cessario dunque conservare in qualche repo-
prescindere dal nome ed a prescindere dal sitory, una specie di tabella di verità che per
gruppo/ruolo di appartenenza, se quell’uten- ogni “operazione” esprima il “si” o il “no” per

N. 70 - Luglio/Agosto 2006 VBJ 29


APPLICATIVI

Figura 1 Creare uno Store Group

ogni utente/gruppo. re determinati Task e/o Operazioni.


Questo repository in NetSqlAzMan si chiama Nel Riquadro “Caratteristiche e Differenze”,
Storage ed è ospitato da un database Sql Ser- vediamo le sostanziali caratteristiche e diffe-
ver (nel pacchetto di installazione è presente renze tra i due prodotti.
lo Script Sql sia per la versione 2000 sia per La struttura che troviamo sia nello Stora-
la versione 2005). ge che visivamente aprendo la console (Start
– Esegui – “NetSqlAzMan.msc”) è quella del
AzMan vs NetSqlAzMan Riquadro 1.
Come accennato prima esiste un prodotto
Microsoft analogo e denominato Authoriza- Store e Store Group
tion Manager (AzMan); AzMan è presente na- Per Store si intende un raggruppamento lo-
tivamente in Windows XP SP1+ e Windows gico di applicazioni. A questo livello è possi-
Server 2003. bile definire due tipologie di oggetti: Store
La sostanziale differenza tra AzMan è Net- Group e Application.
SqlAzMan è che il primo è Role-based, ovvero Gli Store Group sono dei gruppi applicativi
basa tutto sul concetto di appartenenza ad un di: Utenti/Gruppi Windows, altri Store Group
Ruolo e operazioni contenute in ciascun ruolo, (come i ruoli di COM+ o i gruppi di sicurezza
mentre il secondo è Item-based (o se preferi- di Windows); ogni gruppo può essere di tipo
te Operation-based) ovvero utenti o gruppi di Basic o LDAP ovvero definito staticamente,
utenti o gruppi di gruppi che possono o non cioè per selezione diretta, oppure definito di-
possono appartenere a Ruoli oppure esegui- namicamente, tramite una query LDAP, che

30 VBJ N. 70 - Liglio/Agosto 2006


APPLICATIVI

Figura 2 Eseguire la query LDAP direttamente dalla Figura 3 Definizione di Members nel gruppo Basic
console di NetSqlAzMan

NetSqlAzMan risolve a run-time. In questo Gli Store Group hanno una visibilità circo-
modo è ad esempio possibile creare un grup- scritta a livello di Store, quindi saranno vi-
po di utenti Active Directory che abbiamo un sibili da tutte le Application contenute nel-
nome che inizi per “Andrea” e permessi di lo Store.
Dial-In. In Figura 1 vediamo come creare uno
Store Group; nel codice sotto un esempio di Gli Store Group sono l’ideale per implemen-
query LDAP per includere tutti gli Utenti Ac- tare il concetto di “Ruolo Aziendale” ovvero
tive Directory che abbiano un nome che inizi un raggruppamento di persone che in Azienda
per Andrea e permessi di Dial-In ed in Figura svolgono una determinata funzione a prescin-
2 come eseguire la query LDAP direttamente dere poi dai diritti che ciascuno ruolo avrà in
dalla console di NetSqlAzMan. ogni applicazione; ecco alcuni esempi di ruoli
aziendali: “Dirigenti”, “Impiegati”, “Respon-
(&(objectCategory=user)(cn=Andrea*)
(msNPAllowDialin=TRUE))

I Gruppi “Basic” sono inoltre costituiti


da Members e Non-Members ovvero utenti/
gruppi/Store Groups che devono essere
“considerati” nella costituzione dello Store
Group mentre i non-members sono utenti/
gruppi/Store Groups che non deveno esse-
re considerati. In altre parole, l’elenco dei
membri costituenti un gruppo Basic è dato da
{ Members } – { Non-Members}. Dato che i
members/non-members possono essere a loro
volta altri Store Group è possibile realizzare
potenti e complessi gruppi ricorsivi. Nella Fi-
gura 3 la definizione dei Members e dei Non- Figura 4 Definzione di Non-Members in un gruppo
Members di un gruppo Basic. Basic

N. 70 - Luglio/Agosto 2006 VBJ 31


APPLICATIVI

sabili UO”, ecc….

Per chi fosse interessato ad un approfondi-


mento circa la sintassi e le potenzialità del-
le query LDAP rimando a questo interes-
sante articolo di Microsoft sulla sintassi del-
le query LDAP: http://www.microsoft.com/
technet/prodtechnol/exchange/2003/insider/
ldapquery.mspx.

Application e Application Group


Per Application si intende proprio l’applica-
zione che interrogherà a run-time lo storage di
NetSqlAzMan; ricordo che qui la definizione è
puramente logica quindi non è richiesta alcu-
Figura 5 Creare una nuova Application
na corrispondeza con il tipo o il nome dell’ap-
plicazione reale. Per evitare qualsiasi confu-
sione conviene comunque assegnare lo stesso
nome e magari scrivere una breve descrizione • Task: è una macro-funzionalità logica
di ciò che fa l’applicazione nell’apposito cam- dell’Applicazione
po’ come mostrato nelle Figure 5 e 6. o Un Task può avere membri di tipo
Task, Operation.
Un Application Group è identico in tutto e o Esempi di Task sono: “Inserimento”,
per tutto ad uno Store Group con la sola dif- “Modifica”, “Visualizzazione Re-
ferenza che il suo scoping (visibilità) è circo- port”.
scritto alla sola Application in cui è definito; • Operation: è una micro-funzionalità
un Application Group può considerare tra i dell’Applicazione
suoi members/non-members uno Store Group o Una Operation può avere membri solo
ma non può mai accadere il viceversa. di tipo Operation.
o Esempi di Operation sono: “Inserisci
Gli Application Group sono l’ideale per rap-
presentare i “Ruoli Applicativi”.

Item Definitions
All’interno di ogni Application si possono
definire infiniti Item; ogni Item può essere
di tipo Ruolo, Attività od Operazione (Role,
Task, Operation). A ciascun tipo di Item at-
tribuiremo rispettivamente il seguente signi-
ficato logico:
• Role: è un insieme di “utenti” che nel-
l’applicazione possono compiere le
stesse operazioni;
o Un Role può avere membri di tipo
Role, Task, Operation.
o Esempi di Role sono: “Amministrato- Figura 6 Assegnare una descrizione ad un oggetto
re”, “Responsabile”, “Visualizzato- Application
re”.

32 VBJ N. 70 - Liglio/Agosto 2006


APPLICATIVI

Figura 7 Creare una gerarchia tra Role e Task

nuovo utente”, “Modifica utente”, “Vi- due Operation (Item membri). Questo fatto
sualizza Report 1”. sarà di particolare rilievo quando andremo ad
assegnare le autorizzazioni a questi Item, in
Spesso accade che logicamente il poter com- quanto i diritti dati al Task (Item contenitore)
piere una determinata operazione significhi saranno ereditati dalle Operation (Item mem-
automaticamente poterne compiere delle altre bri) ma non avverrà il viceversa (ereditarietà
magari di sotto livello, oppure si può utilizza- verso il basso); chi sarà autorizzato a “modi-
re strumentalmente questo concetto per asse- ficare” sarà implicitamente autorizzato anche
gnare delle autorizzazioni gerarchiche. a poter “inserire” e “cancellare”. In Figura 7
un esempio di questa gerarchia.
Consideriamo, a scopo di esempio, le ope-
razioni di “Cancellazione” ed “Inserimento” Quando avremo creato tutte le Operation
e supponiamo che esistano alcuni gruppi di ed, aggregate in Task logici dell’Applicazio-
utenti autorizzati a “cancellare”, altri autoriz- ne, potremo finalmente dire cosa può fare ogni
zati ad “inserire” ed altri ancora autorizzati a Ruolo applicativo. Creiamo tanti Role quanti
poter sia “cancellare” che “inserire”. In questo sono i ruoli applicativi individuati nell’ana-
caso è opportuno creare un Task “Modifica” e lisi dell’applicazione ed indichiamo per cia-
due Operation “Inserimento” e “Cancellazio- scun Ruolo quali solo i Task di cui quel Ruo-
ne”, quindi entrare nelle proprietà del Task lo si compone.
(dalla console) e dire che esso è composto da

N. 70 - Luglio/Agosto 2006 VBJ 33


APPLICATIVI

Figura 8 Impostare le Authorization di un Item ed eventuali Authorization Attribute

Item Authorizations
Una volta definiti tutti gli Item (Role, Task, Il “cosa” sarà uno degli Item definiti al pas-
Operation) e creata una opportuna gerarchia so precedente.
tra essi, ci dovremo preoccupare di “riempi- • Role
re” questi contenitori con utenti/gruppi reali • Task
e quindi “chi … può fare … cosa”, indicando • Operation
per ciascuno di essi i permessi.

Il “chi” potrà essere uno seguenti oggetti: Se la gerarchia degli Item è stata costruita
• Un utente Windows correttamente, in genere, e a meno di situazio-
• Un gruppo Windows ni particolari, sarà sufficiente assegnare per-
• Uno Store Group messi solo ai Ruoli. Quando un’applicazione
• Un Application Group chiederà a NetSqlAzMan … “posso fare l’Ope-
razione X ?”, il run-time verificherà se l’ope-
Il “può fare” potrà essere una delle seguen- razione appartiene ad un Task che a sua vol-
ti autorizzazioni: ta appartiene ad un Role di cui l’utente del-
• Allow with delegation l’applicazione fa parte.
• Allow
• Deny Se dalla console NetSqlAzMan si seleziona-
• Neutral no una o più Application, o addirittura l’inte-

34 VBJ N. 70 - Liglio/Agosto 2006


APPLICATIVI

ro Store, è possibile visualizzare la gerarchia ad un utente viene dato detto permesso di


degli Items facendo clic destro con il mou- Deny, questo utente non potrà sicuramente
se e scegliendo la voce “Items Hierarchical compiere tale operazione ma non potrà nem-
View” (Figura 11). meno compiere nessuna delle eventuali sot-
to operazioni (Item figli) anche se ad una di
Diamo ora un significato alle quattro auto- queste fossero dati permessi di Allow o Allow
rizzazioni disponibili ricordando che in Net- with delegation; come avviene per le autoriz-
SqlAzMan è presente il concetto di “delega” zazioni del File System e di Sql Server, vince
ovvero un utente che delega un altro uten- il permesso più restrittivo. Viceversa se su un
te a compiere un’operazione a lui originaria- Item vengono dati allo stesso soggetto sia il
mente concessa. permesso di Allow sia il permesso Allow with
delegation vince il permesso meno restrittivo
In particolar modo chi possiede l’autorizza- e cioè Allow with delegation.
zione di “Allow with delegation” potrà sicu- Attenzione che questa affermazione è vera
ramente compiere l’operazione ed in più po- solo per autorizzazioni date sullo stesso Item
trà delegare uno o più utenti a compiere per e non per vale per gli Item gerarchici; Allow
suo conto la stessa operazione. Questo mec- with delegation non viene propagato sugli
canismo di delega, per ragioni di sicurezza, Item figli.
non può essere esteso oltre il primo livello. In Figura 8 la scheramata della console che
Ciò significa che l’utente delegato non potrà consente di impostare le autorizzazioni.
a sua volta delegare un altro utente a com-
piere la stessa operazione (“allow with dele- NetSqlAzMan è Delegate-compliant
gation” non si propaga). Quando un’autorizzazione viene data dal-
l’Amministratore di NetSqlAzMan attraver-
Il diritto di Allow concede le autorizzazioni so la console di amministrazione si parla pro-
a poter compiere quel determinato Item sen- priamente di “Autorization”. Lo stesso mec-
za diritto di delega. canismo può essere essere adoperato in fase
di run-time da utenti speciali che consentono
Il diritto di Deny nega viceversa qualsiasi ad altri utenti di poter compiere una determi-
autorizzazione mentre un’autorizzazione di nata operazione in loro vece. In questo caso
tipo Neutral è invece neutrale, cioè non dice utilizzeremo il termine “delega”.
né “si” né “no”, ma lascia decidere agli Item Per delegare, l’utente delegante deve innan-
di livello superiore. zitutto avere diritti di Allow with delegation
direttamente sull’Item in questione e deve ap-
Le autorizzazioni Neutral esistono al solo partenere al ruolo Sql Server: NetSqlAzMan_
scopo amministrativo e consentono di man- Users. Nello storage sql sono infatti presenti
tenere nello store l’associazione “chi”/”cosa” 3 (tre) diversi Database Roles:
senza però dire se il “cosa” può essere o non • NetSqlAzMan_Administrators
può essere fatto. Un tipico utilizzo dei Neu- (controllo completo)
tral è per quegli Item i cui permessi cambia- • NetSqlAzMan_Users (solo lettura e per
no continuamente, e sarebbe dunque tedioso messo di delega sugli Item con per
aggiungere e cancellare continuamente i sog- messo Allow with delegation)
getti delle autorizzazioni dallo Storage; me- • NetSqlAzMan_Readers (solo lettura)
glio lasciarli lì e modificare solo il permesso
all’occorrenza. Più avanti vedremo come utilizzare il me-
todo Item.CreateDelegate delle NetSqlAz-
Un’ultima considerazione va fatta per le Man API.
autorizzazioni di tipo Deny; se su in Item,

N. 70 - Luglio/Agosto 2006 VBJ 35


APPLICATIVI

NetSqlAzMan è
Time-dependant
Ogni autorizzazione può esse-
re “elargita” per un intervallo di
tempo indeterminato o determina-
to. I due campi Valid From e Valid
To nella finestra delle autorizzazio-
ni indicano rispettivamente la data
(e ora) di inizio e fine validità del-
l’auorizzazione stessa. Combinan-
do questa caratteristica con la pos-
sibilità di aggiungere più di un’au-
torizzazione per soggetto e per in-
tervalli temporali diversi, più l’ere-
ditarietà delle autorizzazioni, più la
Figura 9 Impostazione delle informazioni di
tipologia del permesso (consenti o connessione allo Storage di NetSqlAzMan
nega) è possibile esprimere auto-
rizzazioni che mutano nel corso del
tempo. Si può dire ad esempio che Un tipico utilizzo degli attributi è quello dei
un utente “u1” potrà eseguire l’Item “x” solo dati di profilo di un utente. Supponiamo che
dal 1-gen-2006 al 30-giu-2006 e successivamen- un utente “u1” rivesta in una Azienda IT il
te dal 1-gen-2007 al 30-giu-2007. In questi due ruolo di “Capo progetto” di un certo proget-
intervalli temporali potremo inoltre escludere to “p1”; immaginiamo inoltre che nell’Azien-
periodi specifici, aggiungendo altri permessi da sia stata sviluppata una applicazione che
per intervalli minori e di tipo Deny. consenta ai capi-progetto di monitorare lo sta-
Stesso identico discorso può esser fatto per to di avanzamento dei progetti loro assegna-
le deleghe, in quanto esse sono a tutti gli ef- ti. Supponiamo anche che l’applicazione con-
fetti delle autorizzazioni. templi fra gli altri una operazione “Controlla
SAL” (Stato Avanzamento Lavori). Che succe-
Authorization Attribute de se l’utente “u1” volesse delegare un utente
L’ultimo anello della catena di questa strut- “u2”, risorsa di fiducia del suo team di svilup-
tura è rappresentato dagli Authorization Attri- po, a controllare in sua vece lo stato del pro-
bute ovvero gli attributi di una autorizzazione. getto “p1”? Una delega adoperata da “u1” a
Fisicamente un attributo è rappresentato da “u2” direbbe che “u2 è autorizzato a compie-
una semplice coppia “key-value” (chiave-va- re l’operazione Controlla SAL al posto di u1”
lore) entrambi di tipo stringa. Per ogni Autho- ma non si porterebbe appresso l’informazio-
rization è possibile definire infiniti attributi ne … “…per il solo progetto p1”.
con il solo vincolo che il nome dell’Attribute
(la parte key) dovrà essere univoca per quel- L’aggiunta di un attributo “progetto-p1” (key-
l’autorizzazione. Viceversa sarà possibile de- value) all’autorizzazione di delega da “u1” a
finire un altro attributo con la stessa key in “u2” risolve tale problema; resta il fatto che
un’altra autorizzazione. NetSqlAzMan di fronte ad una richiesta di
“u2” di “posso eseguire l’item Controlla SAL?”
Lo scopo degli Authorization Attribute è risponderà Allow; sarà poi compito dell’ap-
quello di consentire al livello più capillare plicazione leggere gli eventuali Authoriza-
l’aggiunta di informazioni custom per ogni tion Attribute e filtrare l’elenco dei proget-
singola autorizzazione, aumentando così il li- ti da utilizzare per l’operazione. Altri esempi
vello di granularità dei permessi. di attributi sono dati da: “Data di autorizza-

36 VBJ N. 70 - Liglio/Agosto 2006


APPLICATIVI

Creato il database possiamo


far partire la console in 3 diver-
si modi:

• Start – Programmi - .NET


Sql Authorization Manager –
NET Sql Authorization Manag-
er Console

• Start – Esegui –
NetSqlAzMan.msc

• Start – Esegui – mmc e poi


Aggiungi/Rimuovi Snap-In,
quindi scegliere .NET Sql Au-
thorization Manager dall’elenco
e cliccare sul pulsante Aggiun-
gi.

Ora dobbiamo dire a NetSqlAz-


Man qual è lo Storage da gesti-
re – Figura 9; faremo questa ope-
razione facendo clic con il tasto
Figura 10 Un esempio complet di Store
destro del mouse sul nodo .NET
Sql Authorization manager e
scegliendo la voce Storage con-
nection. Specifichiamo dunque
il nome del server ed eventua-
zione”, “UO di appartenenza”, “Settore”, “Di- lemente l’istanza Sql Server sulla quale ab-
partimento”, ecc…. biamo create il database ed eseguito lo script
Sql, il tipo di autenticazione (Sql o Windows),
NetSqlAzMan Snap-In e creazione del il nome dello Storage più eventuali parame-
DataBase Sql Server tri aggiuntivi che finiranno direttamente nel-
Vediamo come implementare fisicamente la stringa di connessione ADO.NET (ad es.
quanto detto finora, attraverso lo Snap-In di “Enlist = false;”).
NetSqlAzMan.
NetSqlAzMan può funzionare in due dive-
Prima di tutto occorre creare un nuovo da- re modalità: “Administrator” e “Developer”;
tabase su Sql Server; il nome che vi consi- la prima non considera Utenti/Gruppi/Well
glio è NetSqlAzManStorage ma qualsiasi altro Know SIDs locali alla macchina ma soltanto
nome va bene uguale, quindi eseguite l’appo- Utenti/Gruppi/Well Know SIDs del Dominio o
sito script che trovate nella cartella di installa- della Foresta Active Directory e non consen-
zione di NetSqlAzMan (c’è sia la versione per te la manipolazione delle Operation (in quan-
Sql Server 2000 che 2005), avendo cura di se- to considerate ad uso degli sviluppatori); la
lezionare il database appena creato (da Query seconda modalità li contempla entrambi. La
Analyzer o Sql Management Studio) prima di modalità “Developer” è stata pensata apposi-
far partire lo script. tamente per la sola fase di sviluppo, quando
l’ambiente di Deployment non è ancora dispo-

N. 70 - Luglio/Agosto 2006 VBJ 37


APPLICATIVI

nibile o comunque noto. In questa modalità using NetSqlAzMan;


sarà inoltre compito dello sviluppatore defi- using NetSqlAzMan.Interfaces;
nire da quali Operazioni si compone ciascun ...
Task (definiti precedentemente dall’analista). string cs = “Data Source=(local);Initial Catalog =
Per cambiare modalità occorre utilizzare la NetSqlAzManStorage;Integrated Secuirty = SSPI;”;
console e, facendo clic con il tasto destro del IAzManStorage storage = new SqlAzManStorage(cs);
mouse sul nodo .NET Sql Authorization Ma- System.Security.Principal.WindowsIdentity identity =
nager, scegliere la voce Options. System.Security.Principal.WindowsIdentity.GetCurrent();
//For each Operation …
A questo punto siamo pronti a creare Store, //Can I do “My Operation” ?
Store Group, Application, Application Group, AuthorizationType authorizaion = storage.CheckAccess(“My
Role, Task, Operation, Authorization e Autho- Store”, “My Application”, “My Operation”, identity,
rization Attribute facendo semplici clic con il DateTime.Now, true);
mouse, tasto destro – New Store, New Appli- switch (authorizaion)
cation, ecc…. In Figura 10 un esempio di Sto- {
re a lavoro finito. case AuthorizationType.AllowWithDelegation:
Quando abbiamo finito salviamo la console //Yes, I can ... and I can delegate
in modo da non dover fornire nuovamente al break;
prossimo avvio le informazioni di connessio- case AuthorizationType.Allow:
ne allo Storage di NetSqlAzMan. //Yes, I can
break;
NetSqlAzMan API – Il Run-Time Engine case AuthorizationType.Deny:
case AuthorizationType.Neutral:
Una volta creata la struttura dalla console di //No, I cannot
NetSqlAzMan, vediamo come le applicazioni break;
possano interrogare lo storage attraverso le }
API del run-time engine. Creiamo dunque la
nostra applicazione (smart client, web, ecc… VB.NET
) con VS.NET 2005 ed aggiungiamo un riferi-
mento all’Assembly .NET NetSqlAzMan.dll. Imports NetSqlAzMan
L’assembly dovrebbe essere visibile nell’elen- Imports NetSqlAzMan.Interfaces
co dei componenti della finestra di dialogo ...
“aggiungi riferimento”; se così non fosse cer- Dim cs As String = “Data Source=(local);Initial Catalog =
catelo nello cartella di installazione di NetSq- NetSqlAzManStorage;Integrated Secuirty = SSPI;”
lAzMan. Dim storage As IAzManStorage = New SqlAzManStorage(cs)
Dim identity As System.Security.Principal.WindowsIdentity
In testa al nostro codice aggiungiamo due = System.Security.Principal.WindowsIdentity.GetCurrent()
clausole using/imports per dichiarare di vo- ‘Per ciascuna Operazione …
lere utilizzare i namespace NetSqlAzMan e ‘Posso eseguire “My Operation” ?
NetSqlAzMan.Interfaces. Ora tutto il codice Dim authorizaion As AuthorizationType =
necessario per interrogare lo storage si ridu- storage.CheckAccess(“My Store”, “My Application”, “My
ce a queste poche righe, come mostrato an- Operation”, identity, DateTime.Now, True)
che nel codice allegato all’articolo: Select Case authorization
Case AuthorizationType.AllowWithDelegation
‘Sì, posso ... e posso delegare
Listato 2: Case AuthorizationType.Allow
C# ‘Sì, posso
Case AuthorizationType.Deny Or AuthorizationType.Neu

38 VBJ N. 70 - Liglio/Agosto 2006


APPLICATIVI

tral • AuthorizationType.Allow: accesso


‘No, non posso consentito senza diritto di delega.
End Select • AuthorizationType.Deny: accesso ne-
gato.
Per prima cosa dobbiamo creare un’istanza • AuthorizationType.Neutral: accesso
della classe NetSqlAzManStorage, fornendo al neutrale (e quindi negato).
costruttore la stringa di connessione al data-
base Sql Server, quindi ricavare l’identità del- Delega applicativa
l’utente che sta utilizzando l’applicazione.
Per ricavare la WindowsIdentity per una ap- Se vogliamo implementare nella nostra ap-
plicazione ASP.NET utilizziamo la proprietà plicazione una pagina .aspx o una Form Win-
LogonUserIdentity della classe HttpRequest dows specifica per consentire agli utenti stessi
della pagina .aspx; se ci troviamo invece in dell’applicazione di delegare, dovremo repe-
una applicazione Smart-Client utilizzeremo il rire prima le seguenti informazioni:
metodo statico System.Security.Principal.Wi • L’Item (Role, Task, Operation) ogget-
ndowsIdentity.GetCurrent(). to della delega;
• chi è l’utente “delegante”;
A questo punto sarà sufficiente fornire al • chi è l’utente “delegato”;
metodo CheckAccess i seguenti parametri di • l’intervallo temporale di validità tem-
input: porale della “delega” (dal … al)
• StoreName (System.String): il nome
dello store informazioni che poi passeremo tutte insie-
• ApplicationName (System.String): il me al metodo NetSqlAzMan.SqlAzManItem.
nome dell’applicazione CreateDelegateAuthorization(…).
• ItemName (System.String): il nome
dell’Item (un Role, un Task od una Partendo dalla classe NetSqlAzManStorage,
Operation). possiamo “navigare” nel DOM di NetSqlAz-
• windowsIdentity (System.Security.Pri- Man utilizzando i metodi accessori GetXXX()
ncipal.WindowsIdentity): l’identità o più semplicemente facendo uso di indexer,
dell’utente come mostrato nei listati 3 e 4, sempre nel
• ValidFor (System.DateTime): Da- codice allegato.
teTime che indica per quale istante
temporale si richiede il controllo (ti- È sempre possibile ed anzi consigliabile ri-
picamente DateTime.Now). cavare a run-time l’elenco degli Item defini-
• OperationsOnly (System.Boolean): ti nello Storage ma di questi dovremo consi-
true per indicare che il l’item dovrà derare solo quelli che hanno il permesso Al-
essere necessariamente una Opera- lowWithDelegation, come mostrato nel listato
tion, false altrimenti (se si vuole con- 5, in quanto solo sugli Item con questo specia-
trollare l’accesso ad un Task o un Ruo- le permesso sarà consentito delegare.
lo).
Listato 5:
La risposta che il metodo CheckAccess for- C#
nirà sarà del tipo enumerativo NetSqlAzMan
.AuthorizationType ed attribuiremo a tale ri- using NetSqlAzMan;
sposta i seguenti significati: using NetSqlAzMan.Interfaces;
• AuthorizationType.AllowWithDelegat- ...
ion: accesso consentito con diritto di string cs = “Data Source=(local);Initial Catalog =
delega. NetSqlAzManStorage;Integrated Secuirty = SSPI;”;

N. 70 - Luglio/Agosto 2006 VBJ 39


APPLICATIVI

IAzManStorage storage = new SqlAzManStorage(cs); quale l’applicazione appartiene; per ricava-


foreach (IAzManItem item in storage[“My Store”][“My re un SID dobbiamo essere in possesso della
Application”].GetItems(ItemType.Role)) Login corrispondente ed in genere occorre-
{ rà dunque una tabella di corrispondenze tra
foreach (IAzManAuthorization auth in item.GetAuthori il nome dell’Utente ad esempio (nome e co-
zations()) gnome) e la sua Login (DOMINIO\Utente). Il
{ .NET Framework 2.0 per fortuna viene incon-
if (auth.AuthorizationType == AuthorizationType.A tro a questa esigenza e ci mette a disposizione
llowWithDelegation) due nuove e fondamentali classi per compie-
{ re questa operazione: System.Security.Princi
//Per questo “item” si può delegare pal.NTAccount e System.Security.Principal.S
} ecurityIdentifier che combinate assieme con-
} sentono di ricavare il SID di un utente data la
} sua Login e/o viceversa; per un esempio ve-
dere il listato 6.
VB.NET
Il SID così ricavato verrà passato come pa-
Imports NetSqlAzMan rametro al costruttore della classe NetSqlAz
Imports NetSqlAzMan.Interfaces Man.SqlAzManSID.
...
Dim cs As String = “Data Source=(local);Initial Catalog = Gli ultimi due parametri sono di tipo
NetSqlAzManStorage;Integrated Secuirty = SSPI;” System.DateTime? (ovvero nullabili) e rap-
Dim storage As IAzManStorage = New SqlAzManStorage(cs) presentano data e ora di inizio e fine validi-
For Each item As IAzManItem In storage(“My Store”)(“My tà della delega. Se uno dei due o entrambi
Application”).GetItems(ItemType.Role) avranno valore nullo si intenderà la delega
For Each auth As IAzManAuthorization In come senza scadenza o senza inizio validità o
item.GetAuthorizations() a tempo indeterminato. Nel listato 7 un esem-
If auth.AuthorizationType = pio di delega applicativa.
AuthorizationType.AllowWithDelegation Then
‘Per questo “item” si può delegare Il metodo NetSqlAzMan.SqlAzManItem.C
End If
Next
Next

Dopo aver individuato l’Item og-


getto della delega e l’identità del-
l’utente delegante (stesso proce-
dimento illustrato nel listato 2) ci
dovremo preoccupare dell’utente
“delegato” ovvero quello al quale
vogliamo concedere il diritto di po-
ter compiere l’Item in nostra vece.
Tale identità è rappresentata uni-
vocamente solo dal SID (Security
IDentifier) dell’utente Windows.
Figura 11 Vista gerarchica degli Item
I SID sono custoditi dall’infra-
struttura Active Directory alla

40 VBJ N. 70 - Liglio/Agosto 2006


APPLICATIVI

reateDelegateAuthorization(…) restituisce DelegateAuthorization(…); i parametri da for-


un’istanza di tipo IAzManAuthorization che nire sono al solito la WindowsIdentity dell’uten-
possiamo utilizzare per aggiungere uno o più te “u1” ed il SID dell’utente “u2” (listato 10).
attributi come mostrato nel listato 8.
Listato 10:
Listato 8: C#
C#
using NetSqlAzMan;
using NetSqlAzMan; using NetSqlAzMan.Interfaces;
using NetSqlAzMan.Interfaces; using System.Security.Principal;
using System.Security.Principal; ...
... IAzManItem item = ...;
IAzManAuthorizationAttribute attr = WindowsIdentity u1 = WindowsIdentity.GetCurrent();
del.CreateAuthorizationAttribute(“My Key”, “My Value”); IAzManSid u2 = ...;
item.DeleteDelegateAuthorization(u1, u2);
VB.NET
VB.NET
Imports NetSqlAzMan
Imports NetSqlAzMan.Interfaces Imports NetSqlAzMan
Imports System.Security.Principal Imports NetSqlAzMan.Interfaces
... Imports System.Security.Principal
del.CreateAuthorizationAttribute(“My Key”, “My Value”) ...
Dim item As IAzManItem = ...
A delega effettuata l’utente “delegato” po- Dim u1 As WindowsIdentity = WindowsIdentity.GetCurrent()
trà così accedere alle funzionalità dell’appli- Dim u2 As IAzManSid = ...
cazione rappresentate dagli Item sui quali è item.DeleteDelegateAuthorization(u1, u2)
stato delegato (il permesso che la delega as-
segna è Allow). Manipolare lo Storage NetSqlAzMan
da codice .NET
Quando si opera con le deleghe diviene fon-
damentale sapere se l’utente ha già delegato Le NetSqlAzMan API sono molto utili per
altri oppure no, semplicemente magari per manipolare lo Storage Sql Server direttamen-
impedire che lo stesso utente possa compie- te da codice .NET. Basti pensare che la conso-
re nuovamente l’operazione di delega sul me- le amministrativa utilizza internamente pro-
desimo delegato. Per fare ciò occorre leggere prio queste API; ne deriva dunque che tutto
le autorizzazioni date su un determinato Item quello che possiamo fare da console lo pos-
facendo uso dei metodi NetSqlAzMan.SqlAz siamo fare anche da codice.
ManItem.GetAuthorizationsOfOwner(…) for- Sarebbe però estremamente lungo ed one-
nendo il SID dell’utente “delegante” oppure, roso descrivere ogni singolo metodo di ogni
per deleghe su specifici utenti il metodo Net- classe presente nel DOM di NetSqlAzMan,
SqlAzMan.SqlAzManItem.GetAuthorizations( si rimanda perciò al chm fornito insieme al
…) passando il SID del “delegante” ed il SID prodotto.
del “delegato”. Un esempio di utilizzo di que-
sti due metodi nel listato 9. Nell’esempio mostrato nel listato 11, utilizia-
mo il DOM per creare a run-time uno Store,
Infine, per eliminare una delega fatta da un una Application, un Role, un Task, una Ope-
utente “u1” ad un utente “u2” esiste il metodo ration e rendere quest’ultima un Item mem-
NetSqlAzMan.SqlAzManAuthorization.Delete- bro del Task ed il Task un Item membro del

N. 70 - Luglio/Agosto 2006 VBJ 41


APPLICATIVI

Requisiti di installazione

• Windows 2000/XP/2003
• .NET Framework 2.0
(http://msdn.microsoft.com/netframework/downloads/updates/default.aspx)
• MMC (Microsoft Management Console) 3.0
(http://www.microsoft.com/downloads/details.aspx?familyid=61FC1C66-06F2-463C-82A2-
CF20902FFAE0&displaylang=it)
• Sql Server 2000/MSDE/2005/Express
(http://msdn.microsoft.com/vstudio/express/sql/download/)

using NetSqlAzMan;
Role; sempre nell’esempio viene creata una using NetSqlAzMan.Interfaces;
Authorization ed un AuthorizationAttribute. using NetSqlAzMan.ENS;
Ricordiamoci che l’utente che eseguirà tale ...
codice dovrà appartenere al Database Role di SqlAzManENS.StoreCreated +=
Sql: NetSqlAzMan_Administrators. new StoreCreatedDelegate(SqlAzManENS_StoreCreated);
...
Le API utilizzano Tdo - Typed Data Object void SqlAzManENS_StoreCreated(IAzManStore storeCreated)
(vedi [3]) per leggere e scrivere da Sql Ser- {
ver e questo implica un aumento delle per- System.Diagnostics.Debug.WriteLine(
formance e tutta la sicurezza (ad esempio no storeCreated.Name + “ store created”);
Sql injection) fornita da Tdo. }

ENS (Event Notification System) VB.NET

Tutte le classi di NetSqlAzMan scatenano Imports NetSqlAzMan


eventi e questo fatto si rivela molto utile se Imports NetSqlAzMan.Interfaces
ad esempio volessimo tener traccia in un log Imports NetSqlAzMan.ENS
di tutte le operazioni effettuate dagli utenti ...
sullo Storage. Inoltre tutti gli eventi possibi- Dim WithEvents ens As SqlAzManENS ‘class-level field
li ed immaginabili di ogni classe, sono stati ...
concentrati e centralizzati in un’unica classe Private Sub ens_StoreCreated(ByVal storeCreated As
ad eventi statici: SqlAzManENS. NetSqlAzMan.Interfaces.IAzManStore)
Handles ens.StoreCreated
L’ENS è un potente e comodo Sistema di No- System.Diagnostics.Debug.WriteLine(
tifica Eventi da utilizzarsi sia a scopo ammi- storeCreated.Name + “ store created”)
nistrativo sia per catturare tutti gli eventi che End Sub
accadono sullo Storage per mano della nostra
applicazione. Nel listato 12 un esempio di uti-
lizzo della classe NetSqlAzManENS. Conclusioni

Listato 12: Credo saremmo tutti d’accordo nel dire che


C# molte applicazioni necessitano o hanno neces-

42 VBJ N. 70 - Liglio/Agosto 2006


APPLICATIVI

sitato nel passato di un sistema centralizzato


di gestione delle autorizzazioni. A chi di voi ad ro di testing. Grazie “Catho”.
esempio fa questo mestiere, sarà capitato si-
curamente almeno una volta nella vita di ave- Bibliografia
re un’esigenza simile per una applicazione.
Come è andata a finire? Tutto a mano? Tutto [1] A. Ferendeles – “Tdo - Typed Data Object
da capo ogni volta? Tutto custom nel DB? 1.0”, VBJ n.62.
[3] A. Ferendeles – “Performance con GAC
Ci sono molte altre feature in NetSqlAz- e NGEN in ASP.NET”, VBJ n.64.
Man, tra cui: [2] A. Ferendeles – “Tdo - Typed Data Object
2.0”, VBJ n.67.
• CheckAccess asincrona (BeginChe-
ckAccess / EndCheckAccess)
• NetSqlAzMan cusom Exceptions
• Tutte le operazioni sullo Riferimenti
Storage posso essere transazionali
(Storage.BeginTransaction/ [3] Tdo home site: http://tdo.sourceforge.net
CommitTransaction/ (documentazione e quickstart).
RollBackTransaction) [4] Sito NetSqlAzMan:
• Import/Export in formato XML diret- http://netsqlazman.sourceforge.net
tamente dalla console (sorgenti, installer, documentazione).
• Import da MS Authorization Manag-
er
• Test delle query LDAP per i gruppi
dinamici dalla console (Store Group e
Application Group)
• Tutte le operazioni fatta dalla console
vengono loggate nella Application Log
della macchina

Il solo fatto che poi sia .NET 2.0 nativo e si


appoggi a Sql Server per lo Storage delle au-
torizzazioni, rendono questo prodotto sicura-
mente interessante e meritevole almeno di
una prova.

Vi ricordo infine che per il tutto, ovvero sia


per la console sia per il run-time engine, è
disponibile il codice sorgente (C#.NET) ol-
tre che ovviamente al pacchetto di installa-
zione (vedi [4]).

Ringraziamenti

Devo rivolgere un particolare ringraziamen-


to a “Catho” che mi ha dato preziosi sugge-
rimenti in fase di progettazione di NetSqlAz-
Man, oltreché a svolgere un minuzioso lavo-

N. 70 - Luglio/Agosto 2006 VBJ 43


C#

Generics in
C# 2.0
L’introduzione della programmazione generica è
sicuramente la novità più interessante del .NET 2.0,
scopriamone le caratteristiche principali.

Generics

di Gian Maria Ricci

que lo stesso, scrivere codice che

L
non opera su un tipo particolare
di dato e che incapsula un set di
a programmazione generica espande for- operazioni standard.
temente le possibilità offerte dai normali linguaggi,
permettendo la creazione di codice “generico”, ov- Nel .NET 1.1 il massimo del-
vero non vincolato ad uno specifico tipo di dato. Il la genericità si ottiene facendo
primo esempio di rilievo di programmazione gene- discendere tutti gli oggetti dal
rica si ha con i template del C++, sui quali è inte- tipo base object, un approccio uti-
ramente basata la libreria STL. Il framework .NET lizzato anche da altri linguaggi
2.0 introduce in maniera analoga il concetto di ge- moderni come il java. Sebbene
nerics, un estensione disponibile in tutti i linguag- questa tecnica permetta un cer-
gi .NET, perché propria del framework. In questo to livello di astrazione dal tipo
articolo l’argomento verrà affrontato nell’ottica del di dato, non è sicuramente pa-
C#, ma i concetti esposti sono naturalmente vali- ragonabile a quello che si può
di anche per Visual Basic e per qualsiasi altro lin- ottenere con un generics o con
guaggio .NET 2.0 compatibile. un template.

L’esempio classico è quello dei


Generics contenitori: in .NET 1.1 è possi-
Il meccanismo dei generics è simile a quello dei bile creare un contenitore gene-
templates in C++, sebbene presenti alcune diffe- rico, come un arraylist, sempli-
renze più o meno marcate. Lo scopo finale è comun- cemente indicando che gli og-
getti al suo interno sono di tipo
Gian Maria Ricci è laureato in Ingegneria Elettronica presso object; così facendo si può in-
la facoltà di Ancona. Si interessa di computer graphics 3D serire al suo interno qualsiasi
(DirectX e Playstation2) e di programmazione in ambiente
dato e si può quindi dire di ave-
Windows. Collabora attualmente con la ActValue consulting
(www.actvalue.com) nella realizzazione di prodotti software re creato un contenitore “generi-
legati al mondo RfID. co”. Purtroppo in questo modo la

N. 70 - Luglio/Agosto 2006 VBJ 45


C#

genericità è eccessiva, il non sapere con cer- Media += (int) list[I];


tezza cosa è contenuto obbliga ad effettuare }
un cast al tipo corretto durante l’accesso, ma
il problema maggiore è comunque la possi- Come si può vedere è necessario un cast
bilità di inserire dati eterogenei e quindi lo- per informare il compilatore che i dati pre-
gicamente incorrelati. Con questo approccio senti nella lista sono di tipo int e se per sba-
avere classi generiche significa rinunciare alla glio al suo interno si trovano altri tipi di dato
tipizzazione dei dati, limitazione che spesso il cast naturalmente fallisce generando un’ec-
non è accettabile. cezione.

Come esempio si consideri un semplice pro- Per ripararci da errori di questo tipo bisogne-
gramma in cui si chiede all’utente di inserire rebbe quindi racchiudere in un try catch ogni
una serie di numeri interi e di calcolarne poi parte di codice che accede al contenuto di un
la media. L’esempio è contenuto nella funzione arraylist, operazione che è assolutamente im-
Main1() del progetto Generics accluso, è scritto proponibile per non ridurre drasticamente la
in C# 2.0, ma non fa uso di generics, bensì di leggibilità del codice. Con il .NET 1.1 l’unica
un normale contenitore. Il ciclo di lettura può soluzione era far derivare una propria clas-
essere fatto in questo semplice modo se da ArrayList o da CollectionBase e fare il
wrapping dei metodi Add(), Index(), etc per ot-
while (InsertLine != “” ) { tenere una collection strongly typed. In pro-
if (Int32.TryParse(InsertLine, out InsertValue)) getti di grande dimensione questo porta ine-
list.Add(InsertValue); vitabilmente ad avere una collection specializ-
InsertLine = Console.ReadLine(); zata per quasi tutti i tipi di dato definito dal-
} l’utente, perdendo così in parte il vantaggio
della genericità e tornando alla vecchia pra-
Una nota va fatta riguardo al metodo TryPar- tica del copia ed incolla, la cui eliminazione
se(), nuova aggiunta del framework 2.0 presen- è lo scopo principale della programmazione
te in tutti i tipi base di dato e che risolve un generica. Questa pratica inoltre è altamente
problema spinoso presente nella vecchia ver-
sione. Con il .NET 1.1 infatti tutti i tipi hanno
il metodo Parse() che permette di convertire un
La programmazione
valore stringa nel tipo di dato richiesto lan-
ciando un eccezione se la stringa non è in un generica riduce
formato corretto. Questo approccio costringe drasticamente la procedura
ad utilizzare blocchi try-catch per intercetta-
re eventuali errori di formato, operazione che del copia ed incolla
rende il codice meno leggibile e che diminui-
sce seriamente le performance. In .NET 2.0
tutti i tipi hanno invece il metodo TryParse() inefficiente, se si ha la necessità di aggiungere
che effettua la conversione richiesta inseren- un nuovo metodo alle collection così genera-
do il risultato nel secondo parametro (che è te è necessario modificare file per file, con il
passato come ref out) restituendo contempo- rischio di dimenticarne alcuni ed avere quin-
raneamente un bool che indica se la conver- di comportamenti incoerenti.
sione è riuscita o meno. Quello che interessa
però è il ciclo che esegue la media Con il .NET 2.0 le classi generiche risolvono
il problema in maniera decisamente più effi-
int Media = 0; ciente, ecco ad esempio come dichiarare una
for (int I = 0; I < list.Count; ++I){ lista di interi:

46 VBJ N. 70 - Liglio/Agosto 2006


C#

Listato 1 Dichiarazione della classe creazione di un’istanza, con la stessa sintassi


generica MyStack del C++ ovvero racchiudendolo tra parentesi
angolari. Ogni istanza di una classe generica
namespace Generics { opera quindi su un tipo ben determinato che
class MyStack<T> { viene specificato in maniera esplicita o im-
T[] basearray = new T[3];
plicita al momento della sua creazione. Nel-
int stackPos = 0;
l’esempio precedente si è quindi ottenuta una
public T Pop() { collezione generica di oggetti interi. La diffe-
if (stackPos >= 0){
T element = basearray[--stackPos];
return element;
}
throw new ArgumentOutOfRangeException(“
Stack is empty”) ; Il supporto ai generics è
}
dato dal framework ed è
public void Push(T element) {
//controllo se c’è abbastanza spazio quindi standard per ogni
if (stackPos >= basearray.Length) {
T[] newarray = new linguaggio
T[basearray.Length * 2];
basearray.CopyTo(newarray, 0);
basearray = newarray;
}
basearray[stackPos++] = element; renza dall’utilizzo di un arraylist standard è
}
che in questo caso la lista accetta solamente
public bool Peek() { interi e non è necessario effettuare operazio-
return stackPos > 0;
} ni di casting durante la lettura del suo con-
tenuto. In questo modo si possono utilizza-
public int Count() {
re collection strongly typed in maniera vera-
return stackPos;
} mente efficiente.

}
Creare una classe generic
} Per comprendere meglio il funzionamento è
interessante mostrare come si scrive codice
generico realizzando una rudimentale classe
che implementa uno stack. Il codice completo
System.Collections.Generic.List<int> list = è mostrato nel listato1 ed ha solamente uno
new System.Collections.Generic.List<int>();
scopo esemplificativo, dato che nel framework
è già contenuta una classe generica stack per-
Una classe generica incapsula infatti una se- fettamente funzionante. La sintassi è sempli-
rie di operazioni che non dipendono dal tipo ce da ricordare, basta indicare il nome del tipo
di dato permettendo quindi la creazione di generico su cui la classe opera, in questo caso
codice che fornisce un set di operazioni stan- T ed utilizzarlo internamente alla classe come
dard altamente riutilizzabile. Un contenitore se fosse un tipo vero e proprio.
è l’esempio più chiaro di codice non legato
ad un tipo di dato specifico che offre metodi Come si è visto nell’esempio precedente il
di inserimento, rimozione, ricerca, ecc., il cui tipo di dato viene specificato solamente in fase
comportamento è assolutamente indipenden- di definizione ed è in questo momento che vie-
temente dagli oggetti trattati. ne generata nell’assembly la classe specifica.
Per comprendere meglio il processo si può im-
Il tipo di dato su cui si deve operare vie- maginare che il compilatore, quando incontra
ne comunque specificato al momento della un oggetto di tipo MyStack<int>, prenda il co-

N. 70 - Luglio/Agosto 2006 VBJ 47


C#

dice della classe generica, sostituisca ad ogni Naturalmente il framework.NET prevede ne-
occorrenza di T il tipo int, dia alla classe un cessità simili e il codice precedente può esse-
nome tipo MyStak_Int ed infine la compili re utilizzato corettamente a patto che venga
assieme alle altre. Il processo vero e proprio rassicurato il compilatore sull’esistenza del
è differente, ma il concetto base è che viene metodo T.Clone(). Con il .NET infatti un tipo
comunque generata una classe specifica per generico T dichiarato come nel Listato1 viene
gestire ogni tipo di dato. chiamato Unbounded type parameter ad indicare
che non sono state specificate restrizioni. In
Per chi fosse abituato ai template del C++ pratica si può pensare che sia lecito utilizzare
la più grande differenza che si incontra è si- il tipo T in ogni situazione in cui sarebbe leci-
curamente l’impossibilità di scrivere codice to utilizzare un generico object, ma non oltre,
che potenzialmente non compila durante la è per questo che non si può assumere che il
fase di istanziazione. Si supponga ad esem- tipo T supporti il metodo Clone(). Questa li-
pio di volere aggiungere alla classe Stack un mitazione può essere superata introducendo
metodo PopCopy() che ritorna una copia del- delle restrizioni, ad esempio dichiarando la
l’oggetto in cima allo stack senza rimuover-
lo dallo stack stesso. In questo modo il chia-
mante può utilizzare la copia senza andare a
modificare l’istanza originaria. Una prima im- Non solo le classi, ma
plementazione potrebbe essere: anche le interfacce ed i
public T PopCopy() { delegate possono essere
if (Peek()) return (T)basearray[stackPos-1].Clone(); resi generici
throw new IndexOutOfRangeException(“Stack is empty”);
}
classe in questo modo:
Questa funzione semplicemente chiama il
metodo Clone() del tipo generico T per ottene- class MyStack2<T> where T:ICloneable {
re una sua copia, ma in fase di compilazione
si genera un errore perché il tipo generico T La clausola where serve per aggiungere delle
non ha una definizione per il metodo Clone(). restrizioni al tipo T; in questo esempio si ri-
Questo può apparire ragionevole per chi non chiede di implementare l’interfaccia ICloneable.
conosce il C++, anche perché la programma- Con questa modifica il metodo PopCopy() vie-
zione generica dovrebbe essere appunto “ge- ne compilato correttamente, dato che il com-
nerica” e non basarsi su metodi che sono in- pilatore è ora certo che il tipo T possieda il
vece specifici di alcuni oggetti. metodo Clone().

In C++ invece un codice analogo è perfetta- Le limitazioni che si possono imporre sono
mente legale e gli eventuali errori sono posti- di cinque tipi. Si può richiedere che il tipo T
cipati al momento in cui si istanzia il template. sia una classe o una struct, utile ad esempio
Se anche in C# fosse valido questo approccio, per evitare operazioni eccessive di boxing ed
si avrebbe la seguente situazione: MyStack<int> unboxing o comunque per capire come ge-
non compila perché il tipo int non ha il meto- stire le copie degli oggetti. Un’altra restrizio-
do Clone(), ma un MyStack<System.Array> compi- ne è richiedere invece che l’oggetto abbia un
lerebbe senza problemi perchè gli array sup- costruttore di default, utile se la classe deve
portano l’interfaccia ICloneable. creare istanze di un tipo generico. Infine si
può richiedere che il tipo erediti da una par-

48 VBJ N. 70 - Liglio/Agosto 2006


C#

ticolare classe o implementi una data inter- }


faccia, l’esempio appena mostrato ricade in }
questo ultimo caso.
Questo metodo, sebbene sembri corretto ad
La programmazione generica non si limita un primo esame, non gestisce correttamente
però alle classi, anche le interfacce possono l’ereditarietà. Si supponga di creare una classe
infatti essere rese generiche in modo da spe- MyString da cui si fa ereditare una seconda clas-
cificare più efficacemente alcune particolari se MyString2. Se si crea un MyStack<MyString> è
capacità di un oggetto, come ad esempio il fat- possibile passare nel metodo Push() un ogget-
to di tipo MyString2, dato che ereditando da
MyString ne mantiene la sua interfaccia. Pur-
troppo questo comportamento non è mante-
La programmazione nuto dal metodo PushStack(), si potrebbe in-
fatti rimanere stupiti del fatto che il compila-
“generica”, a dispetto del tore non permette di passare a questo metodo
suo nome, rinforza la un parametro di tipo MyStack<MyString2>.
tipizzazione Analizzando attentamente la situazione que-
sto comportamento è indubbiamente corretto,
per una classe MyStack<MyString> il meto-
do PushStack() accetta infatti un parametro di
to di essere una lista. Con il .NET 1.1 l’inter- tipo MyStack<MyString> che è sicuramente
faccia IList racchiude una serie di metodi che differente da MyStack<MyString2>.
identificano un oggetto di tipo lista, con l’in-
troduzione dei generics è ora presente anche Il problema deriva dal fatto che, sebbene sia
la controparte IList<T> che identifica invece possibile utilizzare un oggetto MyString2 al
una generica lista di oggetti T. Questa funzio- posto di un MyString a causa della relazione
nalità è assolutamente necessaria, alcune vol- di ereditarietà, le due differenti istanze dello
te infatti si deve iterare su di un contenito- stack non sono legate da nessuna relazione. Il
re di cui non si conosce il tipo esatto. Se non fatto che MyString2 erediti da MyString non
si avesse a disposizione un interfaccia gene- implica infatti che MyStack<MyString2> ere-
rica, si dovrebbe trattare l’oggetto come una diti da MyStack<MyString> e neppure che
IList perdendo i vantaggi della programma- sia ammissibile una conversione implicita.
zione generica.
La soluzione a questo problema è rendere
Metodi generici il metodo Push2() generico facendolo dipen-
La programmazione generica può essere dere da un altro tipo chiamato U, imponendo
adottata anche nei singoli metodi di una clas- come constraint la derivazione dal tipo base
se, ad esempio per dichiarare parametri gene- T. La dichiarazione corretta è pertanto la se-
rici anche quando la classe non è essa stessa guente.
generica. Si supponga ad esempio di estende-
re la classe MyStack, fornendo all’utente un public void PushMyStack<U>(MyStack2<U> stack) where U :
metodo con cui riversare il contenuto di uno T {
stack in un altro stack. Una prima implemen- while (stack.Peek()) {
tazione potrebbe essere la seguente: this.Push(stack.Pop());
}
public void PushStack(MyStack<T> stack) { }
while (stack.Peek()) {
this.Push(stack.Pop()); In questo modo la dichiarazione indica che il

N. 70 - Luglio/Agosto 2006 VBJ 49


C#

metodo PushMyStack() dipende dal tipo gene- ferente e quindi si vengono a creare un nume-
rico U, il quale ha come restrizione la discen- ro molto elevato di delegate. Con il .NET 2.0
denza dal tipo T, ovvero il tipo base generico è possibile invece utilizzare il delegate base
della classe MyStack. Il parametro accettato di nome System.EventHandler<TEventArgs>. Cosi
da PushMyStack () è dichiarato ora come un facendo il framework può gestire ogni even-
oggetto di tipo MyStack2 parametrizzato sul to con un singolo tipo di delegate.
tipo generico U. In questo modo si dichiara
in pratica che il metodo PushMyStack () ac- Naturalmente l’introduzione dei generics
cetta come parametro un MyStack tipizzato porta molte aggiunte alla reflection. Il tipo
su un oggetto che eredita dal tipo T. System.type ha infatti una serie di metodi
dedicati alla gestione dei tipi generici tra cui
Quando si chiama un metodo generico è pos- ricordiamo IsGenericType() che serve per de-
sibile infine specificare al compilatore il tipo terminare a runtime se un tipo è generico o
in maniera esplicita, oppure affidarsi alla de- meno oppure il GetGenericArguments() che recu-
duzione automatica o inferenza. Se ad esempio pera un array di oggetti type utilizzati come
si crea un metodo Swap() generico in grado parametri generici. Addentrarsi nella reflec-
di invertire il contenuto di due variabili ge- tion sui tipi generici è però argomento com-
neriche: plesso che esula da una panoramica introdut-
tiva e può essere approfondito efficacemen-
Public static void Swap<T>(ref T par1, ref T par2) { te nell’msdn.
T temp = par1;
Par1 = par2; Conclusioni
Par2 = temp; L’introduzione dei generics è sicuramen-
} te una delle innovazioni più importanti del
.NET 2.0 perché rende possibile l’utilizzo del-
Lo si può indifferente invocare in uno dei le tecniche di programmazione generica che
due modi. portano a scrivere codice più leggibile con
una drastica riduzione del numero di cast,
Int var1 = +1; di classi contenitore strongly typed e di co-
Int var2 = -1; pia e incolla.
Swap(ref var1, ref var2); //1
Swap<int>(ref var1, ref var2); //2 Il supporto alla programmazione generica è
fornito direttamente dal framework e per que-
sto è disponibile per tutti i linguaggi, sebbe-
Altre particolarità ne ognuno di essi possa comunque adottare
Anche un delegate può essere generico, l’uti- una sua sintassi specifica. I concetti base sono
lità più grande è il poter finalmente definire inoltre universali e quanto visto in questo ar-
in maniera più semplice eventi strongly typed ticolo riguardo al C# si adatta naturalmente
seguendo il pattern consigliato nel .NET fra- anche al Visual Basic e a qualsiasi altro lin-
mework. Questo tipo di pattern consiste nel- guaggio managed che decida di supportare la
l’utilizzare delegate in cui il primo parame- programmazione generica.
tro è un riferimento all’oggetto che genera
l’evento stesso, mentre il secondo argomen-
to è un oggetto che contiene tutti i parametri
necessari per la gestione dell’evento e deve
sempre discendere dalla classe base EventAr-
gs. In .NET 1.1 questo fa si che ogni tipo di
evento ha potenzialmente un argomento dif-

50 VBJ N. 70 - Liglio/Agosto 2006


MOBILE

Common Time
mSuite Security
I principali elementi funzionali e operativi di mSuite Security, prodotto dalla
CommonTime, con particolare attenzione alla sicurezza

C
reare applicativi sicuri per dispositivi Qualsiasi azienda che conside-
mobile non è così facile. ra seriamente la propria strate-
L’afflusso di tali dispositivi non di pro- gia di sicurezza deve rispondere
prietà dell’azienda è causa di preoccupazione per alle seguenti domande:
tre aree distinte: per la proprietà dell’azienda, per
il meccanismo di supporto, e in definitiva per gli • Protezione dei dispositivi
utenti stessi. Chi è autorizzato a utilizzare il
Perché ciò rappresenta un problema? dispositivo?
Perché i dispositivi hanno, e avranno in un pros- È disponibile la versione più
simo futuro, uno storage locale. recente dell’applicazione?
Una possibile risposta a questo problema di sicu- Le firme dell’antivirus sono ag-
rezza potrebbe essere: “Non abbiamo necessità di giornate e l’applicazione antivi-
uno storage locale. Le reti wireless hanno una am- rus è in esecuzione?
pia larghezza di banda, non sono soggette a inter- I dati sono memorizzati sul di-
ruzioni di rete, hanno una copertura mondiale del spositivo in un formato sicuro?
100%, e non sono costose. Se un dispositivo viene perso
Tuttavia, questa risposta non è corretta. La realtà o sottratto, i dati memorizzati
non è affatto quella descritta. sono accessibili?
I dispositivi client dovranno semplicemente man- Se un dispositivo viene sottrat-
tenere i dati localmente, e gli sviluppatori di appli- to, o in caso di tentativi di lo-
cazioni devono continuare a supportare gli scenari gin non autorizzati, si possono
talvolta online, talvolta offline. Finché l’utopia di rimuovere i dati sicuri?
un dispositivo mobile “stupido”, di una copertura
di rete del 100%, e di una infrastruttura a basso co- • Protezione durante il
sto non è una realtà, continueremo ad avere questi transito
rischi nella sicurezza. Come sono protetti i dati du-
La “trinità della sicurezza” riguarda la protezione rante il transito tra l’utente e
dei dati e dei dispositivi in tre aree: nel dispositi- l’azienda?
vo, nella trasmissione dei dati, e infine nei sistemi
business della sede aziendale. • Protezione aziendale
Se un dispositivo viene perso,
qualcuno può utilizzarlo per in-
© 2006 CommonTime Limited
trodursi nei sistemi aziendali?
Come si può essere certi di chi

52 VBJ N. 70 - Luglio/Agosto 2006


MOBILE

Figura 1 Architettura di mSuite Security

si sta connettendo alla propria infrastruttu- mondo esterno”, dovrà essere più che certa
ra? di chi si connette all’infrastruttura, e di qua-
Come si può fornire una sicurezza diretta li servizi sono accessibili. L’autenticazione dei
o delle patch di fix, senza alcun intervento dispositivi client permette al server di veri-
dell’utente? ficare l’utente, e di autorizzarlo ad un parti-
Come si può essere certi che un dispositivo colare servizio di rete, prima di continuare a
sia abbastanza sicuro per permettergli di con- instradare la sessione.
nettersi alla rete?
Il dispositivo sta introducendo virus nell’am- Autenticazione
biente aziendale? Connection Manager Server: Il processo prin-
cipale di autenticazione avverrà nel Connec-
mSuite Security è un prodotto concepito tion Manager Server (CMS). Questo compo-
per fornire le risposte proprio a queste do- nente server fornisce 5 funzioni in mSuite:
mande.
• Autenticazione
Funzionalità • Autorizzazione
• Routing del processo server
Gestione dell’identità del client: • Comunicazione client
protezione dell’azienda • Crittografia “over the air”
Poiché un’azienda cercherà spesso di po-
sizionare la propria rete dietro i confini del Con crittografia (Standard): La suite di codi-
firewall proteggendosi dall’insicuro “sporco ci crittografici (AES 128,192,256) disponibile

N. 70 - Luglio/Agosto 2006 VBJ 53


MOBILE

I moduli di mSuite

mSuite Mobility Framework


Il framework offre una base sicura per l’ambiente mSuite, incorporando alcuni dei componenti di comunicazione e
configurazione modulare elencati di seguito.

mSuite Administration Console


Fornisce un punto centrale di gestione attraverso uno snap-in Microsoft Management Console (MMC). Garantisce una
semplice configurazione attraverso l’ereditarietà di oggetti gruppi e utenti.
La complessità di impostazione viene minimizzata grazie a un Configuration Wizard e all’Help contestuale.

Configuration Server
Fornisce l’accesso al database mSuite di tutti i prodotti mSuite. Questo database contiene la configurazione, i report e le
politiche richieste per eseguire un ambiente mSuite.

Connection Manager Server (CMS)


Il CMS funge da servizio principale di comunicazione per mSuite. Fornisce cinque funzioni:

• Autenticazione client
• Instradamento del servizio
• Ottimizzazione della comunicazione
• Comunicazioni con mSuite Server
• Crittografia AES “over the air”

mNotes Server
Fornisce la sincronizzazione desktop, server e wireless delle email, dei calendari, dei task, dei contatti e del journaling Lotus
Notes/Domino compreso il supporto completo della funzionalità di calendario e dio scheduling per i gruppi di utenti.

mForms Server
Fornisce un sistema RAD di progettazione, testing, implementazione, deployment e gestione delle applicazioni business
per i dispositivi portatili. Attualmente, mForms funziona con l’ambiente CE/Windows Mobile, ma è prevista l’estensione del
supporto ad altri sistemi operativi per dispositivi come Palm e Symbian.

mControl
Fornisce il deployment dell’applicazione, la manutenzione continua e la gestione di politiche per singolo utente di dispositivi.

mSecure PDA
Fornisce la sicurezza fisica delle informazioni memorizzate sul dispositivo. I dati salvati sul dispositivo possono essere
crittografati e il dispositivo può essere protetto dall’utilizzo non autorizzato. Inoltre, l’utilizzo delle applicazioni può essere
autorizzato per un particolare dispositivo, o essere protetto da password.

mNotes Adapter for Thin Clients


Il modulo mNotes Adapter for Thin Clients fornisce all’utente un’esperienza migliorata, spostando sul server alcuni compiti
CPU-intensivi, piuttosto che tentando di svolgerli lato client. L’Adapter viene utilizzato sia con client Palm sia Symbian.

Notification Server
Il Notification Server fornisce le interfacce UDP o SMS a un dispositivo remoto per la trasmissione di piccoli pacchetti di dati
asincroni (datagram) utilizzati per avviare la connessione ai server mSuite per poi procedere alla trasmissione delle ulteriori
informazioni. Ciò può accadere in conseguenza a un processo business, all’arrivo delle email, o a un processo reattivo, o per
fornire l’infrastruttura di “azzeramento dati” nel caso un dispositivo fosse sottratto. In caso di spegnimento del dispositivo,
la richiesta di notifica verrà accodata, e attenderà il dispositivo, o nel caso un SMS “svegli” il dispositivo per processare il
datagram.

54 VBJ N. 70 - Luglio/Agosto 2006


MOBILE

password presente nel database mSuite. Que-


I moduli di mSuite sto processo avviene nel tunnel protetto da
AES (a meno che la crittografia non sia disa-
Componenti mControl bilitata), fornendo un secondo livello di crit-
Tutti gli aspetti di mControl (sicurezza centralizzata, tografia per queste credenziali. La password
policy di deployment e gestione della configurazione
dell’applicazione) sono relativi ai seguenti servizi:
è memorizzata nel database mSuite in un for-
mato irreversibile.
Device Management Server
Funziona in combinazione con il Client Agent Proxy (CAP)
per fornire al dispositivo l’accesso al server. È utilizzato Autenticazione CMS (RADIUS)
dal prodotto mControl per eseguire il deployment delle In alternativa all’autenticazione mCenter, il
policy dell’applicazione. Il Device
Management Server fornisce anche tutte le funzionalità CMS permetterà che l’autenticazione sia ese-
di controllo dell’applicazione mControl e del dispositivo. guita rispetto a un database esistente di cre-
denziali. In tal caso, il CMS funge da client
Client Agent Proxy (CAP)
Il Client Agent Proxy fornisce l’accesso al Device RADIUS e inoltra le richieste di autenticazio-
Resident Agent (DRA), permettendo la manipolazione ne per la verifica esterna.
del registry del dispositivo, del filesystem e object
store. Qualsiasi applicazione mSuite che richiede queste
Remote Authentication Dial-In User Service
modifiche o il deployment delle policy utilizzerà il Client (RADIUS) è un protocollo standard che abilita
Agent Proxy per ottenere ciò. i server di accesso remoto a comunicare con
un server centrale per autenticare gli utenti
Piattaforme supportate
dial-in e ad autorizzarne l’accesso al sistema
Server o al servizio richiesto. Internet Authentica-
Windows 2000 tion Service (IAS) è l’implementazione Mi-
Windows 2003
Windows NT4.0
crosoft di RADIUS, e offre attualmente il sup-
porto per NTLM o per AD (Active Directory).
Client Inoltre, IAS presenta delle estensioni (IASE)
Pocket PC
Pocket PC 2002
per permettere agli sviluppatori di estende-
Windows Mobile 2003 re ulteriormente IAS. Un tipico server RA-
Pocket PC 2002 Phone Edition
DIUS opererà utilizzando i metodi descritti
Pocket PC 2003 Phone Edition
Windows Mobile Smartphone 2002 qui di seguito:
Windows Mobile Smartphone 2003 o PAP funziona allo stesso modo di una
Palm OS 3.5 e versioni successive
normale procedura di login. Il client si auten-
tica inviando al server un nome utente e una
password (opzionalmente crittografata), che il
server confronta con quella presente nel pro-
per le aziende che desiderano rendere sicura prio database. Questa tecnica è vulnerabile
la connessione client/CMS di tutto il traffico agli attacchi di “eavesdropping” (ossia di chi
mSuite. Se già si gestisce un’infrastruttura può cercare di ottenere la password ponendo-
VPN idonea per l’utilizzo dei PDA, si può di- si in ascolto sulla riga seriale o sulla connes-
sabilitare la suite di codici crittografici sup- sione IP) e anche ad attacchi iterati per ten-
portata dal Connection Manager tativi.
o A differenza dell’autenticazione PAP,
Autenticazione CMS (Standard) il protocollo CHAP (Challenge Handshake Au-
Utilizzando l’autenticazione standard in Con- thentication Protocol), invia al client una strin-
nection Manager Server, l’autenticazione vie- ga di “challenge” generata in modo random,
ne richiesta alla connessione della sessione, unitamente al nome dell’host. Il client utiliz-
viene passata a CMS utilizzando un mecca- za il nome dell’host per ricercare il secret ap-
nismo “shared-secret” e viene confrontata ri- propriato, la unisce alla parte “challenge”, e
spetto a una combinazione nota nome utente/ codifica l’intera stringa utilizzando una fun-

N. 70 - Luglio/Agosto 2006 VBJ 55


MOBILE

zione hash non invertibile. Il risultato viene nicazione di autenticazione sicura.


restituito al server unitamente al nome del Il ticketing elimina anche il vincolo che sia
client. A questo punto, il server esegue lo stes- memorizzata una password su un dispositi-
so calcolo, e riconosce il client se giunge allo vo.
stesso risultato. Inoltre, CHAP non richiede Un ticket CMS assume la forma di token sicu-
al client di autenticarsi solo alla prima con- ro basato sul client con diversi attributi, com-
nessione, ma invia le stringhe “challenge” ad presa una chiave di sessione e un periodo di
intervalli regolari per esser certo che il client validità (scadenza). Un ticket sarà valido per
non sia stato sostituito da un utente non au- una particolare community di autenticazione,
torizzato. permettendo a più credenziali di esistere sul
client sotto forma di multi-ticket.
Perché il CMS si comporti da client RADIUS
nell’ambito della propria funzione di provider Questi gli attributi del ticket:
di autenticazione, il client RADIUS deve es-
sere registrato sul server RADIUS. o Ticket opaco (opaque ticket): Si trat-
Parte di questa procedura riguarda l’inseri- ta di una credenziale pass-through, non com-
mento di un secret condiviso sia sul server RA- prese dal PDA. Permette alle informazioni di
DIUS sia sul CMS. In genere, si raccomanda autenticazione di essere trasferite in modo si-
che ciascun secret condiviso sia una sequenza curo dal server di autenticazione ad altri ser-
aleatoria, lunga almeno 22 caratteri, di lette- vizi che autorizzeranno l’utente.
re maiuscole e minuscole, numeri e caratteri
di punteggiatura. Per assicurare l’aleatorie- o Chiave di sessione (session key): È una
tà si utilizza un programma di generazione chiave univoca generata dal server. Piuttosto
random dei caratteri per creare i secret condivi- che memorizzare le credenziali del client, la
si. Un secret condiviso è case-sensitive. Ulteriori chiave di sessione è un puntatore “all’indie-
informazioni su RADIUS sono reperibili nei tro” alle credenziali memorizzate sul server,
documenti RFC 2865 e 2866 dell’Internet En- impedendo il reverse engineering delle cre-
gineering Task Force (IETF) denziali del client. Il client deve presentare
questa chiave nel riconnettersi al Connection
Compromesso tra usabilità e Manager Server (CMS). Altre infrastrutture
funzionalità mobile operano in base al concetto di chiave
una tantum assegnata a un dispositivo, chia-
Le aziende si trovano ad affrontare diversi ve che rimarrà valida sul dispositivo per l’in-
problemi specifici con la sicurezza mobile. Un tero ciclo di vita. Implementando una chiave
motivo principale del fallimento di un pro- di sessione invece di questa “chiave di dispo-
getto è la mancanza di interesse da parte de- sitivo”, il CMS permette a una chiave critto-
gli utente poiché si tratta di una applicazio- grafica che cambia di frequente di assicura-
ne tediosa con cui lavorare. Tuttavia, a causa re una sicurezza estesa.
della natura dei dispositivi mobile, è necessa-
rio un maggior livello di protezione rispetto o Periodo di validità del ticket (ticket va-
a un dispositivo fisicamente protetto presen- lidity period): Il periodo di tempo durante il
te nella sede dell’azienda. quale a una combinazione utente/dispositivo
Il ticketing allevia il processo di riautentica- è permesso accedere ai servizi di una com-
zione permettendo a un dispositivo di connet- munity di autenticazione senza riautenticar-
tersi per un certo periodo di tempo dopo che si. Questo valore è configurabile sul server,
è stata stabilita l’identità dell’utente, permet- ma tipicamente varia da un’ora a un giorno.
tendo all’utente di lavorare indisturbato per
un certo periodo, pur mantenendo una comu- o Processo di autenticazione: Quando

56 VBJ N. 70 - Luglio/Agosto 2006


MOBILE

un client richiede una sessione al Connection tografia AES tra il client e il Communication
Manager Server (CMS), il CMS passa prima Manager Server (CMS)
questa richiesta a un server di autenticazio-
ne, definito nella configurazione del CMS. Si CMS: crittografia AES
tenga presente che potrebbe trattarsi di un Lo standard Advanced Encryption Standard
processo nello stesso CMS o che risiede su (AES) è stato determinato in base a un’analisi
un server remoto, in base alle impostazioni. dei formati crittografici effettuata da 15 orga-
nizzazioni participanti. Il NIST (National In-
A questo punto al client viene uno dei se- stitute of Standards and Technology) america-
guenti attributi: no ha scelto l’algoritmo Rijndael come formato
AES. A differenza di DES, lo standard AES
• Combinazione Username/Password non espone alcun punto di debolezza noto del
• Username/Ticket di autenticazione codice di cifratura. I confronti del NIST rispet-
valido to a DES dimostrano che se un cracker DES
via hardware può “craccare” una chiave DES
Una volta avvenuta la presentazione corret- in un secondo, sarebbero necessari 149 “tri-
ta di uno di questi attributi, il CMS procede- lioni” di anni per il crack di una chiave AES
rà ad eseguire l’instradamento al servizio ri- a 128 bit. L’implementazione AES della Com-
chiesto. monTime si basa sul Security Builder di Cer-
ticom, e la crittografia AES si attiene al docu-
mento Federal Information Processing Stan-
dard (FIPS) 197.
Crittografia dei dati: proteggere i dati
in transito Certificati
Come si è discusso precedentemente, uno dei
Qualsiasi azienda è alle prese con la sfida di punti di forza del CMS è la capacità di gene-
fornire un’infrastruttura mobile che sia pron- rare una nuova chiave AES per ogni sessio-
tamente disponibile e che tuttavia garantisca ne, piuttosto che riutilizzare una chiave ge-
dei costi accessibili. Per questi motivi molti nerata una tantum.
utilizzano Internet come mezzo di comunica- A causa della frequente generazione di que-
zione. Implementando una soluzione Internet, ste chiavi, va considerata la protezione nello
la connettività può essere raggiunta da più scambio della chiave Diffie–Hellman dagli at-
Internet provider, dalle stanze di un hotel via tacchi di tipo “Man in the Middle”. Una cop-
GPRS o GSM. Questa flessibilità ha un prezzo pia costituita da una chiave server e da una
per ciò che concerne lo spostamento dei dati corrispondente chiave client elimina questo
su una rete non protetta, e di conseguenza non rischio.
andrebbe considerata senza aver predisposto Questo certificato server deve essere disponi-
una infrastruttura di crittografia. bile nell’account di memorizzazione del certi-
Molte aziende stanno installando una solu- ficato sulla macchina locale, la macchina su
zione VPN (Virtual Private Network) per più cui è in esecuzione il Connection Manager
aree della propria attività, permettendo l’ac- Server (CMS).
cesso a reti protette da IPSec da qualsiasi di- I certificati vengono inviati ai singoli e alle
spositivo. aziende da organizzazioni riconosciute e fida-
Per le aziende che desiderano adottare una te, dette Certificate Authority (CA)
infrastruttura di messagistica protetta e di ge- La mSuite Console e il CMS devono avere
stione senza dover investire nelle comunica- accesso a un certificato che abbia una chia-
zioni VPN, mSuite Mobility Framework forni- ve privata accessibile dal server (non necessa-
sce l’autenticazione, l’autorizzazione e la crit- riamente una chiave esportabile). Per la ver-

N. 70 - Luglio/Agosto 2006 VBJ 57


MOBILE

sione corrente, si deve trattare di certificati Politica di distruzione dei dati


RSA MD5.
Se un dispositivo viene sottratto, un’azienda
Sicurezza del dispositivo: protezione può dover considerare come il dispositivo si
dei dati (lato dispositivo) comporterà nelle mani di un utente non au-
torizzato. Le applicazioni in esecuzione nel
Il furto e lo smarrimento rappresentano del- mobility framework, possono essere suppor-
le minacce associate all’adozione di disposi- tate da funzionalità di azzeramento dei dati
tivi enterprise sul campo. L’attrazione spesso in due possibili scenari:
scintillante di un PDA o di uno Smartphone
ha un effetto “gazza ladra” sugli opportuni- Azzeramento in caso di login fallito
sti, e benché ci sia ben poco da fare a parte La procedura di azzeramento assicura che
il senso comune per ciò che concerne il fur- i dati sul dispositivo vengano resi irrecupe-
to del dispositivo, va data considerazione al rabili, azzerando le aree crittografate defini-
reale valore del dispositivo: i dati in esso me- te, tra cui:
morizzati.
Queste precauzioni devono essere tenute • Storage esterno
presenti: • Qualsiasi storage interno non-volatile
• Adottare una password “forte” per ese- (come il File Store dell’IPAQ)
guire il login al dispositivo
• Assicurare la protezione contro la sin- E infine restituendo un dispositivo nello sta-
cronizzazione non autorizzata to delle impostazioni di fabbrica.
• Assicurare che i dati siano memoriz-
zati in formato crittografato su tutti i dispo-
sitivi di memorizzazione
• Garantire che i dati siano azzerati in “Pillola letale”, azzeramento remoto,
caso di furto o smarrimento blacklist
• Assicurare che il dispositivo sia sicu- mControl offre la possibilità di utilizzare i
ro da attacchi di rete servizi di Notification del mobility framework
• Assicurare le applicazioni possano es- per assicurare che un dispositivo sia sempre
sere protette contattabile, via TCP/IP su GPRS/Wi-Fi ecc.
• Assicurare che il dispositivo non con- o via messaggi SMS per dispositivi che chiu-
tenga codice subdolo, che impatti la rete. dono la connessione IP.
Questa caratteristica permette un pronto
Benché i meccanismi di autenticazione di hard reset da remoto del dispositivo, spe-
mSuite Connection Manager proteggano cie nel caso di smarrimento o sottrazione del
l’azienda dall’accesso non autorizzato e veri- dispositivo. Altri meccanismi di protezione
fichino l’identità, una password personale sarà come le blacklist forniscono una protezione
necessaria per proteggere il dispositivo. contro la rimozione intenzionale della scheda
Il vantaggio di una mSecure PDA Password SIM. Se il dispositivo si riconnette all’infra-
è che questa viene definita dall’utente, ma la struttura, l’ID del dispositivo resta in blacklist,
policy viene imposta centralmente. e il PDA verrà immediatamente sottoposto ad
Attraverso la mSuite Administration Con- un hard reset.
sole, è disponibile il controllo centrale del-
la policy per i seguenti attributi della policy
di sicurezza:

58 VBJ N. 70 - Luglio/Agosto 2006


MOBILE

Crittografia rapida vs. crittografia


sicura
Uno degli errori più comuni che si commette
nell’utilizzo delle applicazioni di crittografia è
“attivare tutto”, senza rendersi conto di ciò che
esattamente significa crittografare tutto.
La crittografia non è mai senza costo, par-
ticolarmente nei dispositivi di calcolo limi-
tati. Questo sovraccarico delle prestazioni
può essere significativo se non ci si attiene
al buon senso.
La prima fase di implementazione della crit-
tografia locale è comprendere quali dati sono
da ritenersi “necessari da proteggere”. Dopo
aver definito i dati protetti, vanno fatte delle
considerazioni sul se seguire un approccio che
fornisce una completa crittografia AES a 256
bit o se richiedono un algoritmo crittografico
ad alte prestazioni che funziona rapidamente
pur garantendo un livello di sicurezza.

Proteggere il dispositivo: applicazioni


Figura 2 Autorizzazione fallita di esecuzione
applicazione Poiché un’azienda può aver necessità di li-
mitare le applicazioni che possono essere ese-
guite sul dispositivo, mSecure PDA mantiene
Crittografia dei dati: protezione dei facoltativamente un elenco centralizzato del-
dati sul dispositivo le applicazioni non autorizzate ad essere ese-
guite sul dispositivo.
La protezione dall’accesso ai dispositivi mo- Questo meccanismo funziona intercettando
bile è sufficiente solo fino a un certo punto. qualsiasi tentativo di eseguire file eseguibili
Gran parte dei PDA hanno una modalità di attraverso le scorciatoie o attraverso un file
manutenzione o la possibilità di eseguire il explorer, e utilizzando una tabella di lookup di
dump dell’intero dispositivo su un singolo autorizzazione per determinare se a un uten-
file per mezzo dell’interfaccia seriale. Ciò ha te è permesso eseguire questo file.
il vantaggio di rendere il dispositivo facilmen- Qualsiasi tentativo di accesso a una appli-
te flash-aggiornabile, ma comporta l’introdu- cazione non approvata presenterà un dialogo
zione di una breccia nella sicurezza. che spiega che l’applicazione non è autoriz-
Molti dispositivi hanno anche supporti di sto- zata, e richiederà a un amministratore il per-
rage removibili preferiti a causa della natura messo di utilizzo dell’applicazione.
non volatile. Questi dispositivi di storage re- Questa tecnica è stata utilizzata ad esempio
movibili presentano anche un rischio consi- per impedire ai dipendenti di accedere ai gio-
derevole a causa della limitate dimensioni e chi, alla configurazione o anche a Internet, di-
quindi della agevole portabilità. sabilitando Internet Explorer.
È proprio tenendo conto di questi punti che Come tutti i componenti mSuite, questo uti-
la crittografia dei dati locali va considerata lizzo può essere implementato a livello di root,
essenziale. di gruppo o di utente.
Anche gli aggiornamenti del Registry o del

N. 70 - Luglio/Agsoto 2006 VBJ 59


MOBILE

database di configurazione possono essere si modi, tra i quali quello di gran lunga più
gestiti da una policy centralizzata, così come semplice è l’ utilizzo dell’opzione “show me” di
gran parte degli aggiornamenti delle policy mControl dello snapshot dell’applicazione.
vengono memorizzati in queste aree. Questo approccio permette sia al motore
antivirus sia alla configurazione di essere di-
mControl stribuiti in un unico pacchetto. Una opziona-
La sicurezza condivide una relazione sim- le definizione di virus può essere distribuita
biotica con la gestione del dispositivo. Non si a questo punto o essere mantenuta come en-
può realmente imporre la sicurezza senza es- tità separata.
sere in grado di installare, controllare e ma- Le future versioni previste di mControl for-
nutenere il dispositivo. È anche vero che la niranno ai “connettori” antivirus la possibi-
gestione ha pochissimo effetto se il disposi- lità di scaricare e installare automaticamente
tivo non viene mantenuto in uno stato sicu- le definizioni aggiornate direttamente dal sito
ro. Il componente mControl di mSuite ha lo Web di un produttore o via FTP e di mante-
scopo di mantenere il dispositivo in uno sta- nere il controllo e il logging da un unico cen-
to valido noto e in definitiva di assicurare che tro di gestione.
l’utente mantenga la propria concentrazione
sulle funzioni business senza dover preoccu- Come accade per i firewall personali e i pro-
parsi della tecnologia. duttori di antivirus, un’azienda ha spesso del-
I compiti tipici che ostacolano la possibilità le preferenze sui fornitori. È perciò importan-
di un utente di lavorare comprendono: te mantenere un approccio agnostico alla ge-
stione, piuttosto che fornire l’opportunità di
o Perdita di produttività quando si sca- gestire più applicazioni di sicurezza e busi-
rica la batteria del dispositivo ness dalla stessa locazione centrale.
o Perdita di produttività nel cercare di
scaricare la recente patch di una applicazio- Ogni qualvolta un dispositivo viene presen-
ne tato a un mSuite Connection Manager Servi-
o Perdita di produttività dovuta all’in- ce, il primo “servizio dati” a cui si connette-
troduzione di codice subdolo rà sarà mControl. Ciò permette immediati ag-
o Perdita di produttività dovuta alla ve- giornamenti delle policy e delle impostazioni
locità con cui un’azienda richiede il cambio prima che al dispositivo sia permesso conti-
dell’applicazione – la forza lavoro distaccata nuare con gli altri task e servizi mSuite.
può avere necessità di visitare molto raramen- Ciò assicura che un dispositivo abbia una
te la sede centrale, perché ciò dovrebbe cam- sufficiente sicurezza prima che gli sia per-
biare a causa della distribuzione o dell’aggior- messo di continuare.
namento di un nuovo sistema mobile?
Le blacklist sono un metodo di protezione
mControl permette una distribuzione gesti- di un’infrastruttura dall’accesso non autoriz-
ta centralmente delle policy di antivirus ai di- zato. Il processo di disabilitare un particola-
spositivi mobile. Il motore antivirus in genere re dispositivo, anche se le credenziali utente
viene scelto dall’azienda, e sul server viene sono corrette, permette a un amministrato-
generato un pacchetto software di configura- re di bloccare i dispositivi smarriti o sottrat-
zione. Questo pacchetto può essere distribuito ti, o anche di inviare da remoto un comando
a livello di server o di gruppo, ma può anche di azzeramento per mezzo di una rete wire-
essere abbastanza specifico da essere adatta- less o via SMS.
to alle necessità di singoli utenti.
In base al produttore dell’antivirus, il de-
ployment della policy può avvenire in diver-

60 VBJ N. 68 - Marzo/Aprile 2006


.NET TOOLS
NDoc (già a partire dalla versione 2003). Inizialmente
di Raffaele Di Natale il supporto XML era previsto solo per progetti
in C# e per VB .NET era necessario installare
Il tool più utilizzato (ed atteso) per la un tool aggiuntivo denominato VBCommenter
produzione di documentazione del codice [2]. Con la versione 2005 anche questo gap è
negli standard più diffusi stato superato.

NDoc si è affermato negli ultimi anni come Prerequisiti


uno dei tool più diffusi per la produzione di NDoc richiede il .NET Framework 1.0 o 1.1. In
documentazione automatica del codice. Ciò un successivo paragrafo si proporranno alcuni
è accaduto non solo perché è gratuito, ma workaround per eseguire NDoc, con alcune
soprattutto per la sua efficienza, stabilità limitazioni, anche in ambito .NET Framework
e capacità di produrre una completa 2.0.
documentazione basata su HtmlHelp, piuttosto
che Html 2.0 o in formato Latex. Purtroppo
l’ultima release risale al gennaio del 2005 e con Tag per la
l’uscita di Visual Studio 2005 (e l’incremento documentazione XML
di applicazioni basate sul .NetFramework
2.0) sono venuti alla luce tutti i limiti di Per poter utilizzare la documentazione XML
un’applicazione ferma ormai al capolinea da di una libreria di classi bisogna rispettare
troppo tempo. la sintassi prevista: in C# il commento deve
essere del tipo:
Scopo dell’applicazione /// <tag> testo </tag>
NDoc [1] genera la documentazione riguardante
librerie di classi utilizzando essenzialmente mentre in VB .NET sarà:
gli assembly .NET e i file XML prodotti ’’’ <tag> testo </tag>
automaticamente dall’ambiente Visual Studio
In C# potremmo, per esempio, documentare
così il codice di una particolare classe:

using System;
namespace mynamespace
{
/// <summary>
/// Classe d’esempio con documentazione XML per NDoc
/// </summary>
public class myClass
{
/// <summary>
/// L’entry point dell’applicazione
/// </summary>
public static void Main()
Figura 1 Documentazione in formato HmlHelp della classe myClass
{
int a = 2;

N. 70 - Luglio/Agosto 2006 VBJ 61


.NET TOOLS

int b = 3; in Figura 2. In VS2003 si accederà sempre


int c = myFunc(a, b); alla finestra di dialogo relativa alle proprietà
Console.WriteLine(“il prodotto è: “ + c); del progetto e, dopo aver selezionato “Tutte
}
le configurazioni” in corrispondenza di
“Configurazione”, bisognerà accedere alla
/// <summary>
pagina “Generazioni” della voce “Proprietà di
/// MyFunc effettua il prodotto tra a e b
configurazione “ e qui inserire percorso e nome
/// </summary> del file XML da produrre. Rigenerare sempre
/// <param name=”a”>primo parametro</param> la soluzione dopo aver effettuato le precedenti
/// <param name=”b”>secondo parametro</param> modifiche delle impostazioni del progetto al
/// <returns>In risultato dell’operazione</returns> fine di aggiornare la coppia di file assembly/
/// <example> file-XML. Verificare infine l’effettiva presenza
/// <code>
di tali file nella cartella /bin del progetto prima
di importarli dall’ambiente NDoc.
/// int a = 2;
/// int b = 3;
/// int c = myFunc(a, b); Descrizione delle
/// Console.WriteLine(“il prodotto è: “ + c); funzionalità principali
/// </code> Dopo aver creato un nuovo progetto in
/// </example> ambiente NDoc sarà sufficiente premere
public static int myFunc(int a, int b)
sul pulsante “Add” per aggiungere la coppia
assembly/file XML e produrre successivamente
{
la relativa documentazione. Ulteriori
return a * b;
parametri di configurazione, elencati nella
} finestra principale dell’applicazione, possono
} essere utilizzati per personalizzare l’output
} dell’applicazione. Tra questi segnaliamo:
• HtmlHelpName, il nome del file chm
Nel codice d’esempio sono evidenziati finale;
alcuni tag significativi, quali <summary> per il • OutputDirectory, la cartella in cui
sommario, <param> per l’elenco dei parametri verranno salvati i file di help generati
della funzione e <code> per descrivere un
blocco di codice da fornire come esempio nella
documentazione. La Figura 1 rappresenta
Prodotto
NDoc
l’output in formato MSDN (HtmlHelp) di
NDoc ottenuto importando l’assembly e il file Url di riferimento
XML corrispondenti al progetto di cui sopra. http://www.sourceforge.net/projects/ndoc
All’indirizzo [3] è possibile ottenere l’elenco Versione Release
completo di tutti i tag XML che possono essere 1.3.1
utilizzati per la documentazione del codice.
Semplicità d’uso 
Se i commenti al codice sono stati inseriti correttamente, con
NDoc basterà premere un pulsante per avere una documenta-
Configurazione dell’ambiente zione completa e pronta all’suo.
Visual Studio 2003 e 2005 per Utilità 
progetti in C# Le lamentele (tantissime) circa il mancato rilascio della nuova ver-
Per entrambi gli ambienti di sviluppo è sione palesano la diffusione e l’utilità di questa applicazione. Solo a
necessario configurare le caratteristiche pagamento si trovano tool confrontabili con questo prodotto.
del progetto corrente affinché possa Qualità prodotto 
essere generato il file XML relativo alla Si tratta di un tool efficiente e stabile
documentazione. In VS2005 è sufficiente
Qualità documentazione 
accedere al menu “Project” e successivamente La documentazione, disponibile solo in lingua inglese, è chiara ed
cliccare alla voce “Properties…”. A questo esaustiva e sono forniti anche esempi sull’uso dei tag XML.
punto non resta che selezionare la voce
“XML documentation file”, come evidenziato

62 VBJ N. 70 - Luglio/Agosto 2006


.NET TOOLS

con il .NET Framework 2.0 e che


funziona con le dovute limitazioni,
è quella suggerita in [6]: dopo aver
copiato il contenuto della cartella
/bin/1.1 (percorso di installazione di
NDoc) in /bin 2.0, basterà aggiungere
un nuovo file denominandolo
“NDocGui.exe.config” e contenente
Figura 2 Finestra di configurazione progetto C# in Vs 2005 il seguente codice:

<?xml version=”1.0” ?>


<configuration>
da NDoc;
<startup>
• OutputTarget, lo standard di output;
• ShowVisualBasic, se si vuole supportare <supportedRuntime version=”v2.0.50727” />
anche la sintassi in VB per tipi e <supportedRuntime version=”v1.1.4322” />
membri. <requiredRuntime version=”v1.1.4322” />
</startup>
Per quanto riguarda il campo OutputTarget, NDoc </configuration>
consente la generazione di documentazione
basata sui più diffusi standard di help Con questa semplice modifica è possibile
authoring, tra questi: utilizzare NDoc anche sugli assembly
• LateX (beta) prodotti con VS 2005. È un workaround e non
• HtmlHelp rappresenta chiaramente una soluzione al
• Help 2.0 problema, ma consente di produrre comunque
un output accettabile.
Altre impostazioni riguardano direttamente le
modalità di produzione della documentazione, E la Microsoft?
le eventuali estensioni mediante fogli di stile Il responsabile del progetto NDoc ha
proprietari ed il supporto alla localizzazione. motivato nei forum il perché del mancato
Infine NDoc mette a disposizione aggiornamento del tool e l’intenzione di
un’applicazione console denominata rilasciare la nuova versione entro il 2006.
“NDocConsole.exe” che risulta Il vuoto che si è venuto a creare ha però
particolarmente utile nella produzione batch indotto molti utilizzatori di NDoc a rivolgere
della documentazione. la propria attenzione verso altre soluzioni
presenti sul mercato, anche a pagamento. La
NDoc e il .NET Microsoft come ha risposto a tutto questo?
Framework 2.0 Inizialmente non è sembrata preoccupata dai
Come anticipato in precedenza, un grave risvolti: in tanti si sono domandati perplessi
limite della versione corrente NDoc è quella come mai tanto ritardo ad integrare un simile
di non supportare il .NET Framework 2.0. tool direttamente in ambiente Visual Studio.
Negli ultimi mesi c’è stato un certo fermento A tal proposito consigliamo di leggere [7] in
intorno ad un nuovo progetto, sempre sotto cui Microsoft chiarisce la propria posizione
licenza GPL, denominato NDoc 2005 [4] e che rispetto al problema.
rappresenta un fork del progetto NDoc tuttora
in versione beta. I lunghi tempi impiegati
dall’autore di NDoc per rilasciare la nuova Conclusioni
versione, con il supporto al .NET Framework Capita spesso di sentire che la migliore
2.0, ha provocato un proliferare di simili documentazione del codice è rappresentata
soluzioni. Una seconda soluzione al problema dal codice stesso. A questa conclusione si
potrebbe essere quella proposta da [5], anche giunge dopo aver utilizzato uno strumento
se l’affidabilità è tutta da verificare. Un’ultima avulso dal codice stesso o quanto meno non
possibilità, per consentire a NDoc di interagire perfettamente integrato. Dopo aver provato

N. 70 - Luglio/Agosto 2006 VBJ 63


.NET TOOLS

NDoc difficilmente rinunceremo ad esso. tere i parametri della connessione (quali il nome
Infatti, se da un lato il programmatore continua del database, l’utenza e la password) e (opziona-
ad accedere direttamente alla documentazione le) testare se la connessione ha avuto successo.
del codice tramite i commenti al codice stesso, A questo punto si caricano tutte le tabelle del da-
la stessa documentazione può essere resa
tabase tramite l’apposito bottone “Load Tables”
disponibile nel formato help che preferiamo
senza ulteriori passaggi o integrazioni. presente sulla maschera quindi ha inizio la scelta
dei parametri per la creazione del codice.
La scheda “Templates” presenta le possibilità di
Riferimenti scelta per la creazione del codice ma purtroppo qui
[1] http://sourceforge.net/projects/ndoc/ si denotano i limiti di questa applicazione: i tem-
[2] http://msdn.microsoft.com/library/ plate disponibili sono DAO e NHibernate e il lin-
default.asp?url=/library/en-us/dv_vstechart/ guaggio con cui viene generato il codice è il solo
html/VBGeneratingDocs.asp
C#. Come è noto a tutti, purtroppo DAO è una tec-
[3] http://msdn.microsoft.com/library/en-us/
csref/html/vclrfTagsForDocumentationComm nologia obsoleta di accesso ai dati, mentre NHi-
ents.asp bernate è il porting di un tool scritto nativamente
[4] http://sourceforge.net/projects/ndoc05 per Java per generare SQL per caricare e salvare
[5] http://jonas.lagerblad.com/blog/?p=4 oggetti che si mappano ad una base dati.
[6] http://dougrohm.com/cs/archive/2006/01/06/ Un’ulteriore pecca è rappresentata dal fatto che
36.aspx è possibile selezionare la creazione di una nuo-
[7] http://connect.microsoft.com/VisualStudio/ va soluzione, ma quest’ultima verrà creata solo
feedback/ViewFeedback.aspx?FeedbackID=9
in Visual Studio 2003, ed essendo la versione da
3842
noi provata di aprile 2006, ciò risulta senza dub-
bio uno svantaggio per chi utilizza già Visual Stu-
Codus dio 2005.
Generazione automatica di codice
di Fabio Perrone Passiamo ora agli aspetti positivi della maschera

Uno strumento gratuito per generare codice


in automatico Prodotto
Codus versione 1.3.1

Quando è necessario scrivere delle applicazioni, Url di riferimento


http://www.adapdev.com/codus
ogni buon sviluppatore dispone di proprie libre-
rie che riutilizza oppure sfrutta librerie scritte da Stato Release
Stabile
terzi. Tuttavia, scrivere codice per gestire la ban-
ca dati (quindi gli eventuali inserimenti, cancel- Semplicità d’uso 
Non è stata riscontrata alcuna difficoltà nell’utilizzo della sempli-
lazioni, modifiche, ecc.) può essere un’operazio- ce, anche se un po’ spartana, interfaccia utente.
ne noiosa e ripetitiva. A questo punto è possibile
Utilità 
scrivere da soli un tool per la generazione auto- L’idea è buona: permette di ridurre drasticamente i tempi di svi-
matica di codice o usarne uno già esistente, qua- luppo; è necessario adattarlo però alle proprie esigenze
le il protagonista di questo articolo. Qualità prodotto 
Affidabile, nei test sul prodotto eseguiti non ha mai mostrato par-
Codus permette di gestire database Access, My- ticolari problemi.
Sql, Oracle e SQL Server. L’aspetto del program- Qualità documentazione 
ma è un’interfaccia classica con un elemento ta- L’applicazione e la documentazione sono interamente in lingua in-
glese; quest’ultima è solo disponibile on line.
bstrip in alto, un treeview a sinistra ed una serie
di pannelli centrali che permettono l’esecuzione
di una serie di operazioni. Come prima attività è
necessario impostare il tipo di database, immet-

64 VBJ N. 70 - Luglio/Agosto 2006


.NET TOOLS

di scelta dei template: sono presenti alcuni flag, le entità che verranno usate dall’interfaccia uten-
uno per la creazione di un file di build di NAnt te per la convalida dei dati. Oltre a tutto ciò ven-
ed un altro per la creazione di test di NUnit al- gono creati anche dei cosiddetti “Mock Objects”,
l’interno del codice creato in automatico, un altro particolarmente utili per la creazione dei test da
ancora per la creazione in automatico di Stored eseguire poi con NUnit.
Procedure (ovviamente attivo solo per i databa- Il secondo progetto che viene creato è totalmen-
se che lo permettono) ed infine uno per la crea- te dedicato ai test: per ogni classe vengono crea-
zione in automatico di Web Service per esporre i ti in automatico test per l’inserimento, la cancel-
dati tramite questa tecnologia. lazione, la modifica, la selezione di tutti i record,
Il tab “Tables” permette di scegliere quali tabel- la serializzazione degli oggetti business.
le e viste si desiderano per la creazione del codi- La documentazione del prodotto è disponibile
ce, nonchè arrivare a scegliere a livello di singo- solo on line e purtroppo non è completamente sod-
lo campo con possibilità di cambiare il nome del disfacente, anche se vengono comunque spiegate
campo stesso nella classe business. le funzionalità di base del programma.
Una volta impostate tutte le opzioni, è possi- Da ciò che abbiamo scritto, si evince quindi che
bile generare le classi business, cui ora daremo Codus è un prodotto senza dubbio valido ma al-
una breve occhiata. Per ogni tabella selezionata, trettanto migliorabile per quanto riguarda alcu-
vengono create tre collection: una ordinabile, un ni aspetti leggermente obsoleti; controllando sul
dictionary ed una che implementa IEnumerator, sito del produttore è tuttavia già stata pianifica-
così da poter utilizzare i suoi elementi in un ciclo ta la versione 1.4 del prodotto con supporto per
for each. Per ogni tabella o vista vengono quindi .NET 2.0 e per nuovi database, quali Firebird e
scritte le classi astratte con metodi che creano i PostgreSQL.
command per l’inserimento, la cancellazione e la Aspetto non trascurabile è la possibilità di ave-
modifica; è ovvio che queste classi rappresentano re a propria disposizione tutti i codici sorgenti
il “core” di qualsiasi applicazione che debba effet- dell’applicazione, così da poterne fare oggetto di
tuare l’accesso ai dati. Inoltre, vengono create le studio e anche per eventualmente personalizzare
classi di Business Logic che si mappano uno ad a proprio piacere il programma, estendendolo in
uno con le tabelle selezionate che rappresentano base alle proprie necessità.

N. 70 - Luglio/Agosto 2006 VBJ 65


2 ANNI