Generazione di report in PDF con il framework .NET

March 4, 2010 17:49 by f.bernabei

Spesso all’interno di applicazioni abbiamo la necessità di generare report/stampe più o meno complesse, ed in particolare molte volte l’esigenza è quella di poter generare direttamente file in formato PDF, magari senza uscire dalla nostra applicazione o generare anteprime intermedie del risultato. Per farlo ci sono svariate soluzioni e strumenti, a partire dalle suite di reportistica professionali che permettono la generazione di report molto sofisticati, fino ad arrivare a librerie che permettono la sola generazione di documenti PDF a fronte però di una complessa programmazione e composizione da codice del documento finale.

Fortunatamente dalla versione 2.0 del framework .Net è possibile utilizzare un motore di reportistica derivato dai “Microsoft SQL Server Reporting Services” e distribuito con Visual Studio che è possibile utilizzare a tale scopo. Questo componente è in realtà un visualizzatore di report con estensione rdlc (variante “locale” dei file rdl utilizzati da Reposrting Services ed in pratica un formato xml che permette di descrivere template per i report) che permette l’esportazione dei report in svariati formati, tra cui anche il PDF; vedremo che con poche righe di codice è possibile pilotare direttamente la creazione di un PDF senza dover neanche aprire il visualizzatore, con il vantaggio rispetto ad altre soluzione di avere un editor visuale nativo in Visual Studio (nel nostro caso utilizzeremo Visual Studio 2008 SP1) per la definizione del report stesso (esistono inoltre strumenti esterni in grado di editare i file rdlc che rendono ipoteticamente possibile la personalizzazione dei report in un secondo tempo da parte dei clienti stessi).

In questo articolo quindi vedremo in “stile tutorial” i vari step necessari per la realizzazione di una semplice applicazione di test che alla pressione di un bottone esegua tutte le operazioni necessarie per generare un report e salvarlo in formato PDF.

Da bravi programmatori decideremo di rendere il report completamente slegato dalla base dati e gli forniremo quello di cui ha bisogno attraverso il passaggio di oggetti DTO creati ad hoc (o magari già presenti ed utilizzati all’interno della nostra applicazione). Nel progetto di esempio creiamo una classe che rappresenta un ipotetico articolo da stampare con il codice seguente:

   1: public class ReportDataDTO
   2: {
   3:     public int IdArticolo { get; set; }
   4:     public string Descrizione { get; set; }
   5:     public string Dettagli { get; set; }
   6:     public double Costo { get; set; }
   7:     public byte[] Immagine { get; set; }
   8: }

A questo punto possiamo aggiungere al progetto anche il file rdlc, cioè il template del report che utilizzeremo poi per la stampa. Per farlo basta aggiungere un nuovo item e scegliere dalla categoria “Reportings” il template per i report rdlc (nel mio caso l’ho chiamato ReportDemo.rdlc). Appena inserito il nuovo item si dovrebbe aprire automaticamente in Visual Studio 2008 l’editor dei report: dovreste avere qualcosa tipo:

Empty_rdlc
Il prossimo passo consiste nell’associare al template del report il DTO che sarà utilizzato come contenitore per lo scambio dei dati, nel nostro caso la classe ReportDataDTO precedentemente creata. Per farlo è necessario aggiungere una nuova sorgente dati (Menu Data –> Add New Data Source…) attraverso l’apposito wizard al quale dovremo dire di utilizzare un oggetto come sorgente dati e nella schermata successiva selezionare esplicitamente il tipo ReportDataDTO che abbiamo precedentemente creato.

wizard_dati_2
Una volta selezionata la nostra classe DTO possiamo premere direttamente il tasto “Finish” per completare l’operazione di aggiunta sorgente dati. Ora nella finestra “Data Sources” del report (Visualizzabile dal menu Data –> Show data Sources) avremo la sorgente reportDataDTO con l’elenco dei campi pubblici disponibili ed utilizzabili nel report. Non ci resta altro che “creare” graficamente il report aggiungendo con il semplice trascinamento i campi disponibili nell’area di lavoro dell’editor. Ecco il mio risultato:

rdlc_final

La parte di puro “design” è giunta al termine, ora dobbiamo iniziare a sporcarci un po’ le mani con del buon codice C#.

Per prima cosa ritocchiamo leggermente le impostazioni di compilazione del file rdlc all’interno del progetto Visual Studio. Per default i file rdlc vengono “inglobati” nell’eseguibile/libreria come risorse di progetto, mentre in molti casi è preferibile a mio parere lasciare il template esterno (e caricarlo “al volo” per la generazione del report) in modo da permettere correzioni o semplici modifiche estetiche al template senza la necessità di dover ricompilare e ridistribuire l’intero binario dell’applicazione. Per farlo dobbiamo selezionare il file rdlc nel ”Solution Explorer” di VS2008 e modificare alcune proprietà dalla apposita toolbox “Properties”; in particolare bisogna cambiare la proprietà “Build Action” dal default “Embedded Resource” in “None”. Inoltre impostiamo anche la proprietà “Copy to Output Directory” al valore “Copy if newer” in modo da fare una copia del file nella cartella dei binari ad ogni compilazione. Ecco le modifiche finali delle proprietà del file rdlc:

rdlc_prop
Ora siamo pronti per la generazione del report. Nell’applicazione del progetto di esempio aggiungiamo un bottone e nel gestore dell’evento “Click” di quest’ultimo iniziamo le operazioni per la generazione del PDF.

Per prima cosa simuliamo il caricamento dei dati da una ipotetica sorgente dati implementando un metodo che restituisca una lista di oggetti DTO, nel nostro caso sarà in realtà solamente uno. Il codice è banale e non fa altro che creare un’istanza della classe DTO, valorizzarne le proprietà (i dati utilizzati nell’esempio tra l’altro sono di un libro che vi consiglio di leggere Open-mouthed) e restituuirlo:

   1: private ReportDataDTO[] estraiDati()
   2: {
   3:     byte[] rawImg;
   4:     using (System.Drawing.Image img = System.Drawing.Bitmap.FromFile("RocketSurgeryCover.jpg"))
   5:     {
   6:         using (MemoryStream ms = new MemoryStream())
   7:         {
   8:             img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
   9:             rawImg = ms.ToArray();
  10:         }
  11:     }
  12:  
  13:     ReportDataDTO dto = new ReportDataDTO
  14:     {
  15:         IdArticolo = 9847,
  16:         Descrizione = "Rocket Surgery Made Easy: The Do-It-Yourself Guide to Finding and Fixing Usability Problems",
  17:         Dettagli = "It's been known for years that usability testing can dramatically...",
  18:         Costo = 21.99,
  19:         Immagine = rawImg
  20:     };
  21:     
  22:     return new ReportDataDTO[] { dto };
  23: }

Ora si passa alla generazione vera e proprio utilizzando la classe LocalReport che permette di elaborare un report rdlc ed effettuarne la renderizzazione. I passi da seguire sono il caricamento del file rdlc esterno impostando la proprietà “ReportPath”, aggiunta della sorgente dati da utilizzare, esecuzione del render specificando i parametri per generare un file in formato PDF ed infine il salvataggio dei dati risultanti dall’operazione precedente su file system, ed il gioco è fatto.

Il codice seguente (metodo “generaReport” richiamato dal gestore d’evento del bottone) implementa esattamente i passi appena descritti:

   1: private void generaReport()
   2: {
   3:     // Simulazione estrazione dati da una qualsiasi sorgente
   4:     ReportDataDTO[] dtoList = estraiDati();
   5:  
   6:     // Creazione istanza LocalReport e caricamento template rdlc e dati
   7:     LocalReport lr = new LocalReport();
   8:     lr.ReportPath = "ReportDemo.rdlc";
   9:     lr.DataSources.Add(new ReportDataSource("DemoReportPDF_ReportDataDTO", dtoList));
  10:  
  11:     // Elaborazione e render del report in formato PDF
  12:     Warning[] warnings;
  13:     string[] streamids;
  14:     string mimeType, encoding, extension;
  15:     string deviceInfo = "<DeviceInfo>" +
  16:                         "  <OutputFormat>PDF</OutputFormat>" +
  17:                         "</DeviceInfo>";
  18:  
  19:     byte[] bytes = lr.Render("PDF", deviceInfo, out mimeType, out encoding, out extension, out streamids, out warnings);
  20:  
  21:     // Salvataggio del report generato su file system
  22:     string reportFileName = Guid.NewGuid().ToString() + ".pdf";
  23:     using (MemoryStream ms = new MemoryStream(bytes))
  24:     {
  25:         using (FileStream fs = new FileStream(reportFileName, FileMode.Create))
  26:         {
  27:             fs.Write(bytes, 0, bytes.Length);
  28:             fs.Close();
  29:         }
  30:     }
  31:  
  32:     MessageBox.Show("Report generato correttamente: " + reportFileName);
  33: }

Le uniche due note da sottolineare sono:

- Nella fase di aggiunta dei dati deve essere specificato il nome con cui la sorgente dati è configurata all’interno dell’rdlc. Questo valore è presente (e modificabile) andando nel designer del report ed accedendo dal menu “Report” alla finestra “Report Data Sources”.

- La classe LocalReport fa parte del ridistribuibile Microsoft Report Viewer (installato da Visual Studio). Per poter ridistribuire l’applicazione in un PC con il solo framework .Net installato c’è bisogno anche di questo pacchetto scaricabile gratuitamente dal sito MSDN (il download si riferisce alla versione relativa al framework 3.5 SP1). Per l’utilizzo nel progetto è necessario aggiungere un riferimento all’assembly “Microsoft.ReportViewer.WinForms”.

E con questo è tutto, non resta che eseguire l’applicazione, premere il pulsante e se tutto è andato come dovrebbe, nella cartella di esecuzione del progetto dovrebbe comparire per incanto un file PDF più o meno così

pdf_result

 

File allegati:


Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Applicazioni .NET MicroFramework? il MicroGardener!

February 2, 2010 13:06 by g.ruta

Chi ha partecipato all’evento DotNetUmbria che Innovactive ha organizzato lo scorso 15 Gennaio ricorda che una delle applicazioni più complete che abbiamo presentato (.NET MicroFramework ‘onboard’) consiste in una serra domestica il cui microclima può essere impostato a distanza, controllando parametri quali la temperatura, la luminosità e l’umidità del terreno.
In questi giorni abbiamo continuato a lavorare sul nostro prototipo portandolo a rappresentare, a nostro avviso, un sistema completo di monitoraggio remoto della serra; con questo post pertanto, a vantaggio di tutti, presentiamo schematicamente e illustriamo la soluzione completa, lo stato dell’arte del nostro MicroGardener.

MicroGardenerSchema

Come potete osservare nello schema sopra riportato la serra è dotata di sensori per rilevare costantemente il grado di umidità del terreno, la temperatura in prossimità delle piante e la luminosità ambientale. Tali dati vengono trasmessi wireless ad un modulo Tahoe (una scheda di sviluppo, tra le prime sul mercato che ci ha consentito di programmare e sperimentare con il MicroFramework) grazie ad una coppia di moduli XBee. Molto ci sarebbe da dire su questi dispositivi, ma allo scopo del nostro post basta dire che utilizziamo la ‘API Mode’ per configurare il modulo posto presso la serra come dispositivo che autonomamente trasmette i dati letti dai sensori e occasionalmente riceve un comando di attivazione/disattivazione di un attuatore, mentre il modulo posto presso la scheda di sviluppo Tahoe è in grado, grazie alla libreria Micro Framework Toolkit (http://mftoolkit.codeplex.com/) di interpretare lo stack XBee per le due situazioni di ricezione dei dati dei sensori e di invio dei comandi di attuazione.
Il dispositivo che abbiamo presentato nell’ambito del citato evento si fermava appunto al modulo Tahoe, che è dotato di un display LCD e di una serie di tasti per l’interazione con l’utente; il programma MicroFramework realizzato consente di leggere i valori che giungono dai sensori, visualizzarne graficamente l’andamento nel tempo e agire con i comandi sui singoli attuatori (una lampada per la luminosità, una lampada ad infrarossi per la temperatura e la pompa per l’irrigazione del terreno) oppure selezionando una modalità automatica, nella quale il software provvede al mantenimento dei parametri entro i range impostati per il microclima voluto, azionando in totale autonomia gli attuatori.
Un sistema come quello fin qui presentato, ovviamente, si limita a remotizzare il controllo della serra su distanze compatibili con la portata dei moduli XBee e può essere pensato comunque per l’applicazione domestica (o di vivaio) comunque locale. Come rendere il tutto veramente delocalizzato? Utilizzando il web, ovviamente!
Ecco in quale direzione abbiamo esteso il sistema: utilizzando come server web un modulo aggiuntivo ethernet per il Tahoe (prodotto, come il Tahoe, da Device Solutions; oggi nel loro catalogo si trova il modulo Tahoe-II, che già implementa funzionalità ethernet) abbiamo implementato una API REST che espone quanto ci serve per interagire con la serra in termini di lettura dati e impartizione dei comandi; un servizio WCF si occupa di interrogare periodicamente (polling) il server web per tenersi in memoria i dati dei sensori aggiornati; a questo punto sul web abbiamo pensato la possibilità per l’utente di poter controllare la serra con un semplice browser e, per rendere il tutto un po’ più accattivante, un client Silverlight.
I vantaggi di questa architettura sono molteplici in termini di scalabilità e di prestazioni: infatti pensando al servizio in rete locale con il modulo Tahoe l’attività di polling non viene effettuata su web; poi il tutto può essere implementato per più serre, ovvero per molti sistemi serra + XBee + Modulo MicroFramework; in fase di configurazione del servizio WCF impostiamo quali serre gestire (essenzialmente quali indirizzi interrogare con chiamate REST) e, all’atto di chiamata del servizio da parte di un client, il servizio fornirà all’utente la lista delle serre controllate per operare una scelta.
Completa il tutto un sottosistema che renderà felici gli scettici da una parte (se non vedo non credo!) e coloro che comunque vogliono gustarsi anche ‘a vista’ le loro piante o fiori: abbiamo munito la serra di webcam e instradato il segnale proveniente da essa tramite Microsoft Expression Encoder, esponendolo in streaming su server apposito; il client silverlight è stato munito dell’apposito controllo per la fruizione del flusso video in streaming e…
…eccovi il risultato finale!

MicroGardenerClient

Per vedere il sistema funzionante (con la sola avvertenza che attualmente la pompa per l’irrigazione è sostituita da una semplice lampadina per motivi di sicurezza) e provare ‘live’ a controllare la nostra piccola serra collegatevi alla dashboard di test, quindi selezionate ‘Innovactive Garden’ e cliccate su ‘Connect’…
…solo per utenti con il ‘pollice verde’!


Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Logging delle eccezioni con ELMAH, un’introduzione

December 15, 2009 18:04 by M.Poponi

C'è solo una cosa di cui siamo sicuri quando scriviamo un qualunque software: prima o poi accadrà un'eccezione.
Accadrà perchè il software senza bachi non esiste, o perché la bella ma imprevedibile sistemista ha spento il DB, o solo perché l'utente ne sa una più del diavolo.
Gestire le eccezioni a volte non basta, o semplicemente ci è sfuggito quel caso, quel try, quell'inezia che dalla pancia del nostro programma rimbalza direttamente in faccia all'utente. Con la temuta paginona di errore di ASP.NET.
E' necessario quindi, specialmente in ambito web, avere una strategia un po' più sofisticata della semplice pagina di errore di .NET per la gestione o, almeno, per la rendicontazione e la registrazione di quanto è successo. Per capire dove, a chi e possibilmente, perché.
In questo post introdurremi i primi rudimenti dell'utilizzo di un tool open source, ELMAH, che ha come scopo proprio questo: fornire un framework semplice, potente e versatile per il logging e l'archiviazione delle eccezioni generate da un software ASP.NET.
In breve, le features principali di ELMAH sono
-logging automatico delle eccezioni non gestite
-logging delle eccezioni segnalate
-filtraggio delle eccezioni loggate
-utilizzo non intrusivo: basta aggiungere le dll di supporto, modificare il web config della nostra applicazione, e il gioco è fatto
-logging su diversi media: in RAM, su SQL server, Oracle, Acess, sql lite, XML...
-notifiche email degli errori
-report automatico: una pagina web permette di vedere la lista degli errori, i dettagli e persino la pagina errore originale.
-feed RSS degli errori, post su twitter (!) delle eccezioni

Per illustrare l'uso di questo semplice quanto potentissimo componente la cosa migliore è installarlo ed usarlo passo passo. Allegato a questo post trovate il semplice progetto ASP.NET 3.5 che andremo a costruire. Potete scaricare il progetto cliccando qui.

 

1) creiamo una semplice applicazione Web.


l'applicazione avrà una pagina con tre buttons e un link. 
Il primo bottone creerà un'eccezione di index out of bounds, non gestita. Questo è un errore tipico che magari può sfuggirci e, per i motivi più vari, non essere gestito e "finire" in faccia all'utente.

Il secondo istanzierà una classe contenuta in una class library, tenterà l'accesso ad un db utilizzando una stringa di configurazione errata, con eccezione non gestita. Anche in questo caso vedremo come l'eccezione verrà salvata.
Il terzo bottone tenterà anch'esso l'accesso al db, ma l'eccezione verrà gestita. Vedremo come registrare comunque in elmah l'avvenuto problema.

il semplice codice che realizza questi errori è il seguente

   1: protected void Button1_Click(object sender, EventArgs e)
   2:       {
   3:           int[] arr = new int[2];
   4:           arr[0] = 1;
   5:           arr[2] = 100;       
   6:  
   7:       }
   8:       protected void Button2_Click(object sender, EventArgs e)
   9:       {
  10:           liberia lib = new liberia();
  11:           lib.Accedi();
  12:  
  13:  
  14:       }
  15:  
  16:       protected void Button3_Click(object sender, EventArgs e)
  17:       {
  18:           try
  19:           {
  20:               liberia lib = new liberia();
  21:               lib.Accedi();
  22:           }
  23:           catch (ApplicationException ex)
  24:           {
  25:               Response.Write("si è verificata un'eccezione nell'accesso al db");
  26:               Elmah.ErrorSignal.FromCurrentContext().Raise(ex);  
  27:           }
  28:       }


Il link punterà ad una pagina inesistente, per vedere come vengono gestiti anche errori non direttamente generati dal codice.

Eseguendo l’applicazione e cliccando sul primo bottone, ci troveremo davanti alla normale pagina di errore di ASP.NET:

errore1

per prima cosa, ancora prima di installare ELMAH, per evitare che l'utente veda la pagina standard di errore, possiamo creare una nostra pagina in cui comunichiamo che si è verificata una eccezione, error.htm, e impostarla nel web.config come pagina di destinazione in caso di eccezione non gestita, utilizzando il seguente codice:

   1: <customErrors mode="On" defaultRedirect="error.htm">
   2: </customErrors>


per maggiori info sul tag customErrors si può vedere qui http://msdn.microsoft.com/en-us/library/h0hfz6fc.aspx

2) Installiamo  Elmah
Per iniziare dobbiamo scaricare l'ultima versione disponibile di ELMAH, facendo attenzione all'ambiente di destinazione, se è a 64 o 32 bit.
Troviamo la distribuzione qui:  http://code.google.com/p/elmah/

Nella distribuzione troviamo molti files. Un demo standalone che permette di testare le potenzialità di ELMAH e alcune cartelle con dentro i binari. Prendiamo i binari contenuti in bin\net-3.5\Release

e copiamoli nella directory \bin della nostra applicazione.

Aggiungiamo le references agli assembly elmah.dll e sqllite.

3) configuriamo ELMAH e cominciamo a loggare…

A questo punto, per utilizzare ELMAH basta configurare opportunamente il web.config.

Nel file di distribuzione è presente un file di configurazione generico, da cui possiamo “rubare” la configurazione del nostro web.config.

Nel nostro caso scegliamo di salvare gli errori generati su file XML. Questa è una situazione comoda per poter avere gli errori in un formato gestibile a posteriori. Se è possibile possiamo anche pensare di utilizzare SQLlite, o addirittura sql server. Quest’ultima opzione è sicuramente più potente e versatile, ma chiediamoci: se l’eccezione è proprio l’impossibilità di accedere al SQL Server, dove andrà a finire l’eccezione? :)

Come in ogni situazione, scegliamo fra le varie possibilità a disposizione quella che più si confà al problema che stiamo studiando. La potenza di ELMAH si vede anche dal fatto che possiamo cambiare idea in ogni momento, semplicemente riscrivendo il file di configurazione.

Pochi passi ci portano ad avere ELMAH funzionante:

aggiungiamo la sectionGroup nelle configSections

   1: <configuration>
   2:   <configSections> 
   3:     <sectionGroup name="elmah">
   4:           <section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
   5:           <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
   6:         </sectionGroup>

 

aggiungiamo la vera e propria sezione di configurazione, in cui diciamo ad ELMAH di loggare su file XML, nella cartella virtuale /logs della nostra applicazione (ovviamente avremo già creato tale cartella):

 

   1: <elmah>
   2:     <!-- errorLog type="Elmah.SQLiteErrorLog, Elmah" connectionStringName="ELMAH.SQLite" /-->
   3:      
   4:     <errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/logs" />
   5:   </elmah>

 

aggiungiamo ELMAH agli httphandlers e modules. Segnatamente, nel codice che segue, l’ultima riga degli handlers e le ultime due dei modules:

   1: <httpHandlers>
   2:   <remove verb="*" path="*.asmx" />
   3:   <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
   4:   <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
   5:   <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false" />
   6:   <add verb="POST,GET,HEAD" path="public/elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
   7: </httpHandlers>
   8: <httpModules>
   9:   <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
  10:   <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />
  11:   <add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" />
  12:  
  13: </httpModules>

in particolare nella riga

   1: <add verb="POST,GET,HEAD" path="public/elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />

 

diciamo che la pagina in cui vogliamo vedere i report di errore generati sarà la pagina \public\elmah.axd.

Questo se vogliamo poter accedere da non autenticati ad una cartella che in questo caso abbiamo chiamato \public\ che è liberamente accessibile. Chiaramente sarebbe meglio che questa cartella avesse un nome meno ovvio… L’utilità è quella di poter accedere remotamente al report degli errori anche quando l’errore si verifica proprio nel controllo degli utenti.

Dovremmo quindi, se scegliamo di percorrere questa strada, creare una cartella \Public settando opportunamente le politiche di controllo degli accessi. Non dobbiamo creare alcun file particolare al suo interno, segnatamente non è necessario creare elmah.axd.

4) Fatto. Sentito niente?

A questo punto abbiamo la nostra applicazione che logga ogni errore. L’utente finale vedrà solo l’educatissima pagina error.htm, in cui ci scusiamo dell’errore avvenuto. Ovviamente potremmo anche utilizzare una pagina aspx che riprende una eventuale MasterPage, per rendere l’esperienza ancora più indolore.

Se premiamo i bottoni e clicchiamo sul link, sbirciando nella directory \logs vedremo 4 files:

   1: 15/12/2009  17.02            12.789 error-2009-12-15160210Z-f82885d7-74eb-41c8-bc54-e4d72639f51c.xml
   2: 15/12/2009  17.03            15.605 error-2009-12-15160300Z-fa4ecb0c-2d4f-4f85-9a56-f7672cf4bc5e.xml
   3: 15/12/2009  17.03            15.601 error-2009-12-15160305Z-1fe0f86d-454b-4cc4-a357-1fb4bc4aa1a1.xml
   4: 15/12/2009  17.03             7.247 error-2009-12-15160324Z-13e498bf-87c2-4fce-8af9-e10fc312de81.xml

 

che sono i quattro files xml contenenti tutti i dati degli errori avvenuti.

navigando invece sulla pagina \public\elmah.axd avremo un report interattivo degli errori avvenuti:

report

la cosa interessante è che oltre all’ora, all’utente e al tipo di errore, cliccando su details si hanno tutte le informazioni di contesto e di debug che possiamo sperare di avere, dallo stack completo dell’errore a tutte informazioni di contesto http, dal viewstate completo per arrivare perfino alla pagina di errore originale.

conclusioni

Questo post non dà che un assaggio delle potenzialità di ELMAH. Soprattutto la possibilità di innestare in un’applicazione già esistente, senza alcun cambiamento invasivo al codice, di un framework potente e utilissimo per il logging degli errori.

Una volta capito come utilizzare ELMAH e apprezzata la potenza e la facilità d’uso, si potrà approfondirne lo studio e utilizzarne le funzioni più approfonditamente, per esempio leggendo questo articolo: http://code.google.com/p/elmah/wiki/DotNetSlackersArticle.

Buon lavoro e come sempre buon divertimento.


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Visual Studio 2010 – Prime impressioni sulla Beta 2

October 28, 2009 16:28 by L.Maiorfi

Come sicuramente oramai avrete appreso dai numerosissimi blog e siti web che ne hanno dato notizia, nelle scorse settimane è stato reso disponibile il download di una nuova versione beta dell’ambiente di sviluppo di riferimento su piattaforma Microsoft.

Il nuovo aggiornamento di Visual Studio farà parte di un salto generazionale di gran lunga più consistente di quanto è avvenuto con il rilascio della versione 2008, in quanto per la prima volta da 5 anni a questa parte assisteremo alla pubblicazione di una nuova runtime (la versione 3.5 del Framework utilizza infatti i componenti “core” di .NET 2.0), denominata con ammirevole fantasia .NET 4.0.

Sono moltissime le novità introdotte, letteralmente a 360 gradi, da Microsoft con questa nuova “sessione” di rilasci che avrà luogo molto probabilmente nel mese di Marzo 2010, ed è quindi molto difficile orientarsi nel tentativo di distinguere quello che effettivamente cambierà il modo di sviluppare applicazioni per chi fa questo come attività professionale rispetto alle novità che invece dimenticheremo dopo i primi minuti di utilizzo (qualcuno si ricorda dell’eco data dalle prime recensioni di Visual Studio 2005 alla funzionalità che evidenziava in giallo e verde le righe modificate o aggiunte ad un sorgente tra un salvataggio ed il successivo?).

Ad ogni modo, da qualche parte bisognava pure iniziare e noi abbiamo installato il nuovo Visual Studio all’interno di una macchina virtuale VirtualBox con sistema operativo Windows 7 Starter Edition (il tutto all’interno di una macchina fisica Vista 64 con 4Gb di ram).

Le prime impressioni, che vogliamo condividere attraverso qualche screenshot, non possono non tenere conto della completa riscrittura dell’IDE, che ora utilizza WPF, che ora vanta un’interfaccia utente molto più ricca ma, a dire il vero, anche sensibilmente più lenta, anche se su questo punto converrà esprimersi solo una volta valutata la versione definitiva e in un ambiente non virtualizzato.

Il primo screenshot si riferisce ad una panoramica dell’editor testuale (C# e XAML nell’esempio riportato) che grazie alla versione di WPF contenuta in .NET 4 raggiunge dei livelli di leggibilità del testo su LCD veramente notevoli, anche a dimensioni relativamente piccole (8 e inferiori).

Editor

Nella seconda immagine abbiamo riportato una piccola testimonianza di quello che crediamo migliorerà la vita di chi come noi spende molte ore del proprio tempo facendo debugging (non perché il software scritto sia buggato, sia ben chiaro…), ossia la possibilità di “ancorare” un quickwatch alla riga contenente l’espressione sotto controllo, come il contenuto di textbox1.Text ed il parametro “e” nell’esempio sotto (notate il piccolo pushpin nel tooltip/quickwatch).

Quickwatch pinned

Da non trascurare poi la nuova suite di designer per la modellazione, in grado di produrre diagrammi UML quali Sequence, Class Diagram, grafi di dipendenza tra classi, namespace, assembly e molto altro.

3

Sono state integrate inoltre le funzionalità di editing T-SQL di SQL Server Management Studio 2008, come illustrato nell’immagine seguente:

4

Ultimo ma non ultimo, non è da trascurare che ogni nuova release di Visual Studio accorpa di fatto tutte le estensioni (o almeno quelle ufficiali) rilasciate successivamente all’ambiente di sviluppo, quali ad es. ASP.NET MVC e ASP.NET MVC 2, Silverlight 3, Azure SDK, ecc.

La lista dei template di progetto built-in è infatti molto nutrita:

Template progetti


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

EQATEC Tracer e Profiler

September 16, 2009 11:48 by l.maiorfi

Quante volte ci è capitato di rimpiangere di non aver debitamente “instrumentato” un’applicazione per far sì che fossero loggate le chiamate ai vari metodi (ed i relativi parametri) nel momento in cui si presenta un problema in produzione?

Lo scenario tipico è rappresentato dalla telefonata del cliente che vi dice “ho fatto questa cosa e l’applicazione si è bloccata e l’ho dovuta chiudere da Task Manager”, oppure “ho cliccato sul tasto stampa ma il programma non ha fatto niente”, oppure ancora “per l’operazione che fino a ieri mi ci metteva pochi secondi oggi il programma mi fa aspettare qualche minuto”, e così via…

Bene, oggi abbiamo testato due prodotti free della EQATEC (http://www.eqatec.com/) che saranno di grande aiuto per risolvere le situazioni di cui sopra.

Il Tracer consente di “instrumentare” un insieme di assembly .NET contenuti (necessariamente) nella cartella specificata (con tanto di drag&drop), di cui verrà creata una copia allo scopo. Verrà quindi popolato un treeview con la struttura degli assembly e dei metodi singolarmente tracciabili. Ad ogni esecuzione di uno dei metodi selezionati il tracer visualizzerà il nome del metodo chiamato ed il valore dei parametri in ingresso (solo per i tipi base, però).

Notevole, veramente.

EQATEC Tracer

Il Profiler funziona in maneira analoga, ma traccia anche le durate della chiamata di ciascun metodo, oltre a diverse altre informazioni utili.

Alcune di osservazioni:

  • il tracing e/o il profiling può avvenire addirittura via rete TCP/IP, permettendovi di fare diagnostica sulla macchina del cliente rimanendo comodamente seduti dietro la vostra scrivania (VPN permettendo)
  • i tool della EQATEC sono realizzati come applicazioni WPF
  • in fase di compilazione, l’approccio migliore per l’instrumentazione automatica del proprio codice resta a nostro avviso PostSharp + Laos

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Test della UI di una applicazione con Selenium

September 4, 2009 15:17 by F.Bernabei

Al giorno d’oggi predisporre dei test automatici sulle applicazioni che sviluppiamo è divenuto un requisito fondamentale per vari motivi. Primo fra tutti per evitare che a seguito di modifiche al software (per introdurre nuove funzionalità o correzione di bug) si possa in modo automatico, verificare che tutte le funzionalità precedenti (o meglio tutte quelle precedentemente messe sotto test e verificate) continuino a funzionare in modo corretto e che non si siano quindi introdotti ulteriori bug con le modifiche apportate (questi sono detti test di [non] regressione).

In questo articolo parleremo in particolare di test automatizzati dell’interfaccia utente, argomento che ho già introdotto in un mio post precedente pubblicato su DotNetUmbria.org a cui si può far riferimento per un’introduzione di base.
A differenza degli unit test, l’automatizzazione della UI permette di fare controlli ad un “livello più alto” ed integrato, utile per testare in modo ripetitivo un intero caso d’uso della nostra applicazione o aggiungere un set di test completo ad applicazioni già esistenti.
Come illustrato nell’articolo introduttivo appena menzionato, esistono vari framework per raggiungere il nostro scopo  e sicuramente due dei più utilizzati sono WatIn e SelniumHQ (di cui parleremo in modo approfondito nel prosegui dell’articolo). Si tratta di framework che permettono il test di applicazioni WEB come vedremo in seguito, ma va segnalato che esistono soluzioni analoghe anche per il test di applicazioni Windows, come l’ottima Microsoft UI Automation  per il test di applicazioni Windows Presentation Foundation che magari potrebbe essere argomento per un articolo futuro.

Ma torniamo allo scopo principale di questo post, ossia vedere un esempio concreto di implementazione di un test di un’applicazione reale implementato mediante l’uso di Selenium. Come caso d’uso per provare le funzionalità di base del framework ho scritto una piccola applicazione ASP.NET che banalmente permette di inserire del testo in una casella di testo ed alla pressione di un bottone riporta il testo inserito in una etichetta. Il risultato finale in esecuzione è visibile nell’immagine seguente ed il codice è scaricabile direttamente dal link presente al termine dell’articolo.

uitestwebapp

Come si evince dall’immagine in realtà ci sono due bottoni che eseguono l’operazione appena descritta. Questo per poter provare diversi approcci di test in quanto in un caso l’aggiornamento dell’etichetta viene fatto con codice lato server ed il bottone esegue quindi un postback (all’interno di un UpdatePanel Ajax) e nel codice C# della pagina viene aggiornato il testo.
Nel secondo caso invece il lavoro viene eseguito completamente lato client con del codice Javascript, facendo uso anche del comando alert per visualizzare una finestra di messaggio in modo da vedere come interagire con questo elemento in fase di test.

Eccoci ora arrivati all’implementazione vera e propria dei test. Come anticipato in questo caso utilizzeremo SeleniumHQ che mette a disposizioni diversi strumenti per raggiungere il nostro scopo tra cui i principali sono:

Selenium IDE: Un ambiente integrato distribuito come plug-in per FireFox per la creazione rapida di test e suite di test. I test creati possono essere salvati in diversi formati ed editati direttamente dall’IDE ed essere rieseguiti in qualsiasi momento.

Selenium Remote Control (RC): Un insieme di librerie e tools per scrivere e pilotare i test direttamente da codice. Fornisce un insieme di librerie utilizzabili da svariati linguaggi di programmazione (C#, Java, PHP, Ruby e altri) e permette di eseguire i test praticamente su tutti i browser più diffusi.

Selenium Grid: Un sistema per “espandere” Selenium RC e consentire l’esecuzione dei test in parallelo su server multipli.

Partiamo con Selenium IDE in modo da poter subito prendere contatto con le possibilità offerte dal framework. Dopo averlo scaricato ed installato lo troveremo in FireFox nel menu “Tools –> Selenium IDE” e da qui possiamo lanciarlo. SeleniumIDE

Una volta aperto, l’IDE si presenterà più o meno come in figura e già in modalità di registrazione attiva (identificabile dal bottone con “pallino rosso” premuto nella parte destra della toolbar in alto), il che significa che ogni azione che noi faremo nel browser da cui lo abbiamo aperto, verrà registrata nello script corrente e potrà essere riprodotta in modo automatico rieseguendo il test in seguito. Non ci resta che inserire nella barra degli indirizzi di FireFox l’URL a cui raggiungere l’applicazione (nel nostro caso http://localhost:53771/ visto che stiamo effettuando il test di una applicazione in esecuzione in Visuall lStudio e che gira quindi su una porta creata dinamicamente del Web Development Server), premere invio per avviare la navigazione ed eseguire tutte le azioni che devono essere registrate per essere poi ripetute in seguito. Per esempio i seguenti passi:

  1. Scrivere qualcosa nella casella di testo (nell’esempio ho inserito “Bernabei”)
  2. Premere sul bottone con etichetta “Saluta via javascript”
  3. Premere OK sull’alert che appare
  4. Verificare che sull’etichetta appaia il testo “Ciao Bernabei!”

Quest’ultimo punto ovviamente non corrisponde ad un’interazione che facciamo con il browser, quindi dobbiamo “spiegare” a Selenium come farlo e questo si traduce banalmente nel premere il tasto destro del mouse sull’etichetta che vogliamo controllare. Nel menu contestuale di FireFox appariranno anche tutte le azioni che Selenium può “eseguire” su quel determinato elemento, fra le quali quella che ci verifyTextPresentinteressa che è “verifyTextPresent”. Selezionando il comando viene aggiunto nello script correntemente in registrazione l’istruzione richiesta che effettua il controllo specificato al passo numero 4.

Ora lo script è pronto per essere salvato per rieseguirlo in futuro (per farlo basta caricarlo nell’IDE e premere l’apposito pulsante “Play” della toolbar) o editato manualmente all’interno dell’ambiente. In quest’ultimo caso è possibile farlo aggiungendo i comandi alla lista visualizzata, specificando appunto il comando da eseguire selezionabile da una lista molto ampia di azioni possibili (il set di comandi disponibili è chiamato “selenese”), il target ossia l’elemento della pagina a cui il comando si riferisce ed il valore se necessario per il comando specifico. Alternativamente si può modificare lo script agendo direttamente sul “sorgente” accessibile selezionando il tab “Source” dell’IDE e modificando manualmente i comandi che verranno eseguiti dallo script (questa modalità ovviamente richiede la conoscenza dei comandi messi a disposizione dal framework in quanto non è presente un qualcosa tipo IntelliSense che può aiutare a compilare lo script.

Prima di concludere vale la pena dare uno sguardo al sorgente dello script che per default viene rappresentato usando una sintassi HTML. In pratica si tratta di un HTML contenente un tag TABLE in cui ogni riga TR corrisponde ad un comando da eseguire e contiene tre celle TD che rappresentano comando, target e valore.

Lo script appena creato viene rappresentato in HTML nel modo seguente:

   1: <?xml version="1.0" encoding="UTF-8"?>
   2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
   3:  
   4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
   5: <head profile="http://selenium-ide.openqa.org/profiles/test-case">
   6:     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
   7:     <link rel="selenium.base" href="http://localhost:53771/" />
   8:     <title>New Test</title>
   9: </head>
  10:  
  11: <body>
  12: <table cellpadding="1" cellspacing="1" border="1">
  13:     <thead>
  14:         <tr><td rowspan="1" colspan="3">New Test</td></tr>
  15:     </thead>
  16:     <tbody>
  17:         <tr>
  18:             <td>open</td>
  19:             <td>/</td>
  20:             <td></td>
  21:         </tr>
  22:         <tr>
  23:             <td>type</td>
  24:             <td>txtNome</td>
  25:             <td>Bernabei</td>
  26:         </tr>
  27:         <tr>
  28:             <td>click</td>
  29:             <td>//input[@value='Saluta via javascript']</td>
  30:             <td></td>
  31:         </tr>
  32:         <tr>
  33:             <td>assertAlert</td>
  34:             <td>Stai per essere salutato...</td>
  35:             <td></td>
  36:         </tr>
  37:         <tr>
  38:             <td>verifyTextPresent</td>
  39:             <td>Ciao Bernabei!</td>
  40:             <td></td>
  41:         </tr>
  42:     </tbody>
  43: </table>
  44: </body>
  45: </html>

Dallo stesso IDE è possibile visualizzare lo script in un altro formato riutilizzabile poi da Selenium RC per eseguire il test direttamente da codice. Ad esempio scegliendo il formato C# la rappresentazione dello stesso script è la seguente:

   1: using System;
   2: using System.Text;
   3: using System.Text.RegularExpressions;
   4: using System.Threading;
   5: using NUnit.Framework;
   6: using Selenium;
   7:  
   8: namespace SeleniumTests
   9: {
  10:     [TestFixture]
  11:     public class Untitled
  12:     {
  13:         private ISelenium selenium;
  14:         private StringBuilder verificationErrors;
  15:         
  16:         [SetUp]
  17:         public void SetupTest()
  18:         {
  19:             selenium = new DefaultSelenium("localhost", 4444, "*chrome", "http://localhost:53771/");
  20:             selenium.Start();
  21:             verificationErrors = new StringBuilder();
  22:         }
  23:         
  24:         [TearDown]
  25:         public void TeardownTest()
  26:         {
  27:             try
  28:             {
  29:                 selenium.Stop();
  30:             }
  31:             catch (Exception)
  32:             {
  33:                 // Ignore errors if unable to close the browser
  34:             }
  35:             Assert.AreEqual("", verificationErrors.ToString());
  36:         }
  37:         
  38:         [Test]
  39:         public void TheUntitledTest()
  40:         {
  41:             selenium.Open("/");
  42:             selenium.Type("txtNome", "Bernabei");
  43:             selenium.Click("//input[@value='Saluta via javascript']");
  44:             Assert.AreEqual("Stai per essere salutato...", selenium.GetAlert());
  45:             try
  46:             {
  47:                 Assert.IsTrue(selenium.IsTextPresent("Ciao Bernabei!"));
  48:             }
  49:             catch (AssertionException e)
  50:             {
  51:                 verificationErrors.Append(e.Message);
  52:             }
  53:         }
  54:     }
  55: }

Da notare che se l’IDE viene impostato per rappresentare lo script nei formati per Selenium RC non sarà più possibile utilizzare la visualizzazione di default dell’IDE stesso, quella in formato tabellare che permette di aggiungere comandi selezionandoli da una ComboBox.

L’utilizzo dell’IDE consente dunque di creare in modo rapido delle suite di test (è possibile caricare più script alla volta nell’IDE ed eseguirli tutti in una volta) da rieseguire all’occorrenza per verificare il comportamento della UI. Se questo non fosse sufficiente, o se si volesse organizzare un test per controllare il funzionamento dell’applicazione su più di un browser anche diverso da FireFox, basterà utilizzare le API messe a disposizione dal Remote Control per personalizzare in modo estremamente capillare il comportamento del test.

In allegato a questo articolo è possibile scaricare i sorgenti del progetto WEB di test utilizzato e due script che “utilizzano” in modo diverso l’applicazione testandone una volta il comportamento implementato con il postback asincrono e l’altra come nell’esempio descritto in precedenza che fa uso di javascript.

Buon test a tutti Winking!

 

File allegati:

 


Currently rated 4.5 by 2 people

  • Currently 4.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Utilizzo di Twitter da un’applicazione .NET

August 28, 2009 15:39 by F.Bernabei

Per un piccolo progetto interno abbiamo la necessità di interfacciarci con twitter ed eseguire alcune operazioni comuni come ad esempio ottenere i tweet che stiamo seguendo oppure aggiornare il nostro stato.

Dopo un rapido sguardo alle API messe a disposizione ho pensato: “possibile che non ci sia qualcuno che ha già scritto una bella libreria per utilizzare codeste API da .NET?”. Detto fatto, con l’aiuto del prode Google sono partito alla ricerca ed ho trovato tweet#, bellissima libreria tipizzata e con interfaccia fluente che mette a disposizione (credo) tutte le funzionalità accessibili con le API native (a cui ovviamente si appoggia).

Di seguito un esempio di utilizzo per ottenere la lista di tweet seguiti da uno specifico utente:

   1: var twitter = FluentTwitter.CreateRequest()
   2:     .AuthenticateAs("username", "password")
   3:     .Statuses().OnFriendsTimeline()
   4:     .AsJson();
   5:  
   6: IEnumerable<TwitterStatus> response = twitter.Request().AsStatuses();

Si tratta in conclusione di una libreria ben fatta e molto potente per aggiungere il supporto a Twitter al nostro software… ora non resta che utilizzarla.


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Uno sguardo a MVC#

August 26, 2009 16:50 by g.ruta

MVC# è un ambiente che facilita l’implementazione, in ambiente .NET, di una architettura a tre livelli secondo il pattern MVP (Model-View-Presenter).
Gli autori nel presentare il loro lavoro (qui il sito ufficiale) ci introducono alle più o meno sottili differenze tra MVC (Model-View-Controller) e MVP, poi spiegano come quest’ultimo risolva parte della complessità del precedente e sia più adatto agli ambienti di programmazione odierni, giustificando così la loro scelta di implementare MVP, infine dichiarano che per il loro prodotto useranno la dicitura ‘controller’ anziché ‘presenter’ (da qui il nome MVC# e, a mio avviso, una certa confusione tra pattern e nomenclatura, ma tant’è!).

I concetti alla base del pattern sono pochi: ogni applicazione si compone di una serie di task (ovvero una serie di azioni che portano a termine un compito o risolvono un problema), ogni task comporta il coinvolgimento dell’utente e comunque il passaggio attraverso più interaction points, ognuno dei quali

    • riceve ed elabora i datti immessi dall’utente
    • inoltra le opportune richieste agli oggetti business
    • interroga e/o modifica lo stato del task
    • invia un feedback all’utente

Nell’ottica della semplificazione si associa ogni interaction point ad una vista (view) realizzata poi con una sola classe, alle spalle della quale ci sarà la corrispondente classe controller a realizzare lo strato applicativo e a dialogare con gli oggetti business (domain); prendo a prestito lo schema presente nel sito di MVC# per visualizzare graficamente il tutto:

MVP

Ora veniamo nello specifico al valore aggiunto di MVC#, che si propone appunto di semplificare l’uso di MVP da parte degli sviluppatori.
Per quanto detto sopra l’applicazione è organizzata in task: ebbene anzitutto ogni task della applicazione deve essere ‘avviato’, poi deve essere possibile navigare all’interno del task (ovvero effettuare transizioni attraverso i suoi interaction points), e da un punto di vista di User Interface deve essere possibile usare diverse piattaforme (web o Windows). Per il primo punto MVC# fornisce la classe TaskManager che espone un metodo

public ITask StartTask(Type taskType)

che crea un’istanza del task del tipo passato come parametro, una della classe TaskInfo che popola con le caratteristiche del particolare tipo di task richiesto e un’istanza della classe Navigator che associa al task per poi invocare il metodo OnStart() del task; la classe Navigator a sua volta fornisce il metodo Navigate(…) che consente il passaggio da un interaction point ad un altro appoggiandosi sulla classe ViewManager che ovviamente ha diverse implementazioni a seconda della piattaforma usata per realizzare la UI (MVC# si applica a UI realizzate con Winforms, asp.net Webforms, SIlverlight e .NET Compact Framework): il comportamento generale è sintetizzato in una interfaccia IViewsManager.
Ogni vista, poi, deve essere creata la prima volta che viene ‘navigata’ e pertanto la Classe ViewManager è in grado di avere, a partire dal tipo della vista, una classe ViewInfo (indipendente dalla piattaforma per la quale la vista è realizzata) popolata e una ViewInfoCollection alla quale aggiungere le viste nuove alla loro prima creazione; ad ogni creazione di una vista, poi, si ha anche l’associazione della stessa al suo controller: secondo quanto previsto da MVP infatti deve essere possibile accedere al controller dalla vista e viceversa.
Resta ancora un legame previsto da MVP, tra il controller e il task, perché deve essere possibile dal controller accedere al task per modificarne lo stato e per poter effettuare navigazioni tra i suo interaction points. Questo si realizza ancora per il tramite della classe Navigator responsabile di tenere i controller per i suo task e che espone il metodo GetController.

In poche parole in effetti l’ambiente risparmia la scrittura di tanto codice e permette di implementare il pattern MVP egregiamente. Noi lo abbiamo sperimentato con una UI Silverlight 2 e in effetti abiamo raggiunto una buona produttività in tempi brevi.


Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Velocizzare un inserimento “bulk” con NHibernate

August 26, 2009 12:07 by L.Maiorfi

Nonostante l’autore, il solito Ayende, confessi che il titolo originale del post dovesse essere “Stupid Performance Tricks”, quella che trovate qui è una piccola guida tutt’altro che stupida ad alcuni semplici accorgimenti che velocizzano una procedura di inserimento di test di 500.000 record portandola da 400 record/secondo a 3.200 record/secondo.

Quello che sorprende ancora di più è che il risultato ottenuto attraverso l’uso di un ORM è più o meno collocato al 30% della massima velocità ottenibile (attraverso SqlBulkCopy), in un “terreno” (quello delle operazioni bulk) tradizionalmente molto sfavorevole agli ORM.


Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Proposta per argomenti da trattare nelle giornate di autoformazione Innovactive – Parte 2

July 8, 2009 16:02 by L.Maiorfi

5) SMC (State Machine Compiler), un generatore di codice per realizzare macchine a stati finiti (realizzate secondo il pattern State) in pochi minuti. Consuma un linguaggio di markup proprietario in cui si elencano gli stati, le transizioni, le azioni da fare prima, dopo e durante l’ingresso ad ogni stato. E’ stato utilizzato in GestioneSinistri2007 e nel nuovo PlasmaFrost.

6) PostSharp, un framework (composto da una class library e un addin per Visual Studio) per lo sviluppo dei componenti dedicati all’AOP (Aspect Oriented Programming). In altri termini, con questo tool (ora Open Source, ma frutto di molti anni di sviluppo) potrete definire degli attributi (con cui marcare classi, metodi o interi assembly), detti “aspects” (in quanto trasversali a tutta l’applicazione, come ad es. la tematica della sicurezza o della gestione delle eccezioni, o il logging, ecc.) che in fase di compilazione permetteranno a PostSharp di “iniettare” della logica custom che modifichi il comportamento del metodo o della classe o dell’assembly cui è applicato. Un esempio per tutti è quello dell”instrumenting” di un’applicazione per generare un log utile ad una analisi post-mortem a seguito di un bug riscontrato solo dal cliente: non so quali metodi “decorare” e quindi o azzardo o me li passo tutti; aggiungo codice sempre uguale ma non abbastanza generico, come quello per loggare i valori dei parametri in ingresso e dei valori di ritorno di ciascun metodo (a meno di voler usare la reflection); dopo aver deciso che nel logging voglio aggiungere qualcosa mi affido a qualche avventuroso “trova e sostituisci”, ecc. ecc.

7) PLINQO, un insieme di template per codesmith che generano codice Linq2Sql (dbml, classi entità, datacontext e varie altre amenità) molto più completo e utile di quello generato dal tool built-in di Visual Studio. Ad es. è possibile così gestire la sincronizzazione di entità disconnesse o realizzare relazioni molti-a-molti, tra le altre cose

8) SqlCe, un database simile a SqlLite ma compatibile al 100% con il T-SQL di SQL Server, che lavora “in-process” con il proprio client e può essere deployato insieme alla propria applicazione (è rappresentato da uno sparuto numero di dll). Il database è rappresentato da un file e può essere utilizzato dall’omonimo (e omologo) DB su sistema operativo Windows CE. Adattissimo per applicazioni desktop monoutente e/o per data layer molto semplici e/o per hardware poco carrozzati. Noi lo utilizziamo sul progetto PlasmaFrost insieme a PLINQO e Linq2sql.

9) PEX, uno spaventoso framework corredato di add-in per Visual Studio che non mancherà di impressionare chi utilizza lo Unit Testing come pratica per aumentare la qualità e la robustezza del proprio codice. In due parole, PEX estende il concetto di Unit Test alla sua forma “parametrica”, in cui un certo test viene eseguito non in una sola forma, ma viene sottoposto a differenti “condizioni” di esercizio, rappresentate da altrettante combinazioni dei parametri del test. Certo è che però che se dovessimo testare un metodo che prende una lista di string e due int in ingresso non riusciremmo a provare tutte le combinazioni neanche se avessimo a disposizione 1000 anni di tempo. Non senza PEX, per lo meno. PEX infatti effettua un’analisi “white-box” per capire qual’è il set minimo di parametri da utilizzare per mettere alla prova un certo metodo ed effettua il test con il set di valori individuati. Nel caso di un metodo di media complessità, con meno di 100 esecuzioni PEX “capisce” se esistono vulnerabilità ed eventualmente suggerisce una soluzione. PEX si porta dietro inoltre un generatore di Stubs pe il Mocking di interfacce e classi astratte.

10) FileHelper: sapere che esisteva ci sarebbe stato utile in più di un’occasione…

11) Watin e Selenium, per il test automatico delle applicazioni web. Belli e utili. A mio avviso, contando un risparmio di 2 minuti a sessione di debug per poter arrivare navigando a mano fino al punto in cui l’applicazione non funziona a dovere, il test automatico può far risparmiare il 50% del tempo.

12) Coolite: non ne so niente, ma mi piacerebbe vederlo in azione…


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5