Trovare gli errori di binding in WPF e generare un’eccezione

Tip veloce che può fare risparmiare parecchio tempo.

Quando si effettua il binding in WPF è molto facile commettere errori di battitura (sempre che non si usi il designer o Blend) oppure è possibile modificare o eliminare la property nel ViewModel senza aggiornare lo XAML.

Ad esempio se credo un binding sbagliando la sintassi della property Description nel Path:

<GridViewColumn DisplayMemberBinding="{Binding Path=Descrition}" Header="Last name" Width="140" />

a runtime non viene visualizzato nulla ma soprattutto non viene sollevata nessuna eccezione.

Il metodo più veloce per visualizzare gli errori di binding è quello di eseguire l’applicazione in debug da Visual Studio: in questo modo tutti gli errori di binding vengono loggati nella finestra di Output.

Nell’esempio mi ritrovo un errore di questo tipo:

System.Windows.Data Error: 40 : BindingExpression path error: ‘Descrition’ property not found on ‘object’ ”Product’ (HashCode=55303339)’. BindingExpression:Path=Descrition; DataItem=’Product’ (HashCode=55303339); target element is ‘TextBlock’ (Name=”); target property is ‘Text’ (type ‘String’)

A questo punto potrebbe essere utile loggare questi errori sotto forma di eccezione anche a runtime (magari con Log4net).

In questo post viene spiegato come creare un listener sui binding di WPF per generare un’eccezione: Making WPF Binding Errors Exceptions

Share

Differenze tra web application e web site in Visual Studio

Ancora oggi mi capita spesso di trovare clienti che non conoscono la differenza tra un progetto di tipo Web Site ed uno di tipo Web Application in Visual Studio.

new-web-site

new-web-application

Web site project (WSP)

I progetti di tipo web site sono compilati dinamicamente. Sul web server vengono pubblicate tutte le pagine e i controlli con il markup ma anche tutti i sorgenti C#/VB.Net.

Ogni pagina è compilata la prima volta che viene richiesta e viene generata un’assembly per ogni file.

L’unico aspetto comodo dei web site è che è possibile seguire un ciclo di modifica tipico di un sito ASP classic in cui si modifica la pagina e la si pubblica senza dover ricompilare l’intero progetto.

Ovviamente in scenari anche minimamente complessi non è certamente questo il motivo per scegliere di sviluppare un progetto web site.

Tra l’altro la proliferazione di queste DLL combinata con l’eventuale frequente modifica dei namespace potrebbe causare errori di runtime.

I web site project hanno una cartella particolare App_Code in cui è possibile inserire direttamente delle classi C#/VB.Net. Anche queste devono essere copiate sul web server e vengono compilate dinamicamente.

Continuous integration e deploy

I web site non si integrano facilmente nei processi di Continuous Integration. Ad esempio un web site non consente di gestire gli eventi di pre e post build.

Il deploy viene effettuato tramite un normale XCopy oppure da Visual Studio sfruttando il tool Copy Web Site.

Copy-web-site

Web application project (WAP)

I progetti di tipo web application sono precompilati in un’unica DLL.

In questo caso il deploy riguarda le pagine ed i controlli con il markup ma non i file di code behind che vengono sostituiti dall’unica DLL nella cartella Bin.

Al contrario di un web site per pubblicare una modifica è necessario ricompilare l’intero progetto.

Continuous integration e deploy

La web application genera una normalissima assembly .Net semplificando il deploy ed il testing.

Anche il versioning risulta facilitato in quanto come ogni assembly contiene tra le altre le informazioni di Assembly Version e File Version.web-application-publish

Per effettuare il deploy si può usare lo strumento Publish di Visual Studio oppure creare un Deployment Package che può essere direttamente installato in IIS.

In entrambi i casi gli artefatti da mettere sul web server contengono esclusivamente pagine e controlli e le DLL delle cartella bin.

Tutti i file esclusi a livello di soluzione ed i sorgenti non vengono copiati/impacchettati.

Riassunto delle principali differenze

Web site Web application
Compilazione Dinamica, un’assembly per ogni singola pagina.
Effettuata la prima volta che viene richiesta la pagina o ad ogni modifica
Compilazione dell’intera web application e generazione di un’unica assembly
Deploy Deploy di pagine e controlli.
Deploy di tutti i file sorgenti di code behind
Deploy di pagine e controlli.
Deploy dell’assembly generata nella cartella bin
Strumenti di deploy Copy web site Publish
Build deployment package
Continuous Integration Non dispone di eventi di pre/post build Gestisce gli eventi di pre/post build
L’assembly contiene le informazioni di versione
Gestione file Tutti i file su file system sono obbligatoriamente compresi nel web site project Granulare:
– è possibile escludere dei file a livello di progetto in Visual Studio
– è possibile specificare quali file compilare/copiare/embeddare

Concludendo non esistono dubbi per me che la soluzione per ogni progetto che sia minimante più grande della gestione dei DVD di casa debba essere sviluppata tramite una web application.

Tra l’altro la compilazione in Visual Studio di un Web Site di una certa dimensione risulta molto più lenta di quella di una Web Application.

Può capitare di avere ancora dei vecchi progetti web site. Consiglio la lettura dell’articolo di Scott Guthrie che elenca gli step necessari per fare l’upgrade e le modifiche necessarie.

Riferimenti

ASP.NET: Web Site or Web Application?

Upgrading VS 2005 Web Site Projects to be VS 2005 Web Application Projects

Share

Anatomia di una User Story card – Retro

Continuo la saga sul tema delle user stories.

Dopo i due post:

vediamo adesso cosa contiene il retro di una user story card.

User-story-back

Ricordo che la User Story parte da una frase che descrive ciò che un utente fa o vorrebbe fare su un sistema o comunque nel suo lavoro quotidiano ed è scritta nel linguaggio dell’utente.

A questo punto le informazioni necessarie e che richiedono un alto livello di visibilità per tutti sono:

  • quali task e attività servono per completare concretamente la storia?
  • quali test devono essere scritti o implementati per garantire il livello di qualità richiesto e soprattutto per verificare con il cliente che la user story è effettivamente completa?
  • quanto manca per finire?

Le risposte a queste tre domande si trovano sul retro della user story card.

I test di accettazione (UAT)

In fase di planning è necessario elencare quali saranno gli User Acceptance Tests (UAT) che dovranno essere implementati per soddisfare questi requisiti:

  • servono in fase di analisi per chiarire ulteriormente le idee al cliente
  • servono a chi sviluppa per poter dire “ho fatto” e spostare quindi la user story card in “Done”
  • servono in fase di Demo Meeting per dimostrare e verificare che la user story è stata correttamente implementata e che l’implementazione fa ciò che ci si aspettava.

L’elenco dei task

Quando la scheda entra in una sprint deve essere già stato analizzato quali sono i passi da compiere per completare la User Story.

Elencando i task si ottengono questi vantaggi:

  • di nuovo viene stimolata la scomposizione della User Story in attività più piccole (ed in questo contesto in attività concrete quali sviluppo di righe di codice, attività di infrastruttura, realizzazione di DB ecc ecc)
  • viene data una stima dei task in ore. Dato che la User Story è già temporalmente limitata, la stima dei task che sono attività dettagliate e ancora più piccole dovrebbe essere più realistica
  • i task possono essere eseguiti in parallelo da sviluppatori (o pair programmer) diversi

Nota bene: è solo in questo contesto che compare per la prima volta il tempo, tipicamente in ore, come unità di misura. Ricordo che fino ad ora la User Story è stata stimata in Story Point e quindi svincolata dal fattore temporale.

La scomposizione in task ed ore e la relativa somma consentono di fare un controllo incrociato con gli Story Point per avere un ulteriore conferma della stima della User Story.

Ricordo sempre che lo spazio sulla scheda è limitato e quindi sia i test di accettazione sia i task non devono necessariamente essere esaustivi ma devono essere un promemoria per stimolare la comunicazione.

Il tempo residuo

Infine la domanda più importante, più frequente e con il maggiore grado di incertezza nella risposta: quanto ci vuole per terminare?

Tutto il lavoro di scomposizione, analisi e stima fatto fino ad ora sulla User Story Card viene riassunto nella somma delle ore residue che viene mostrata nella User Story Card e che deve essere aggiornato ogni giorno (normalmente dopo lo stand-up meeting e può essere fatto dallo Scrum Master).

E’ importante notare che in questa fase non è di alcun interesse parlare di ore lavorate ma di ore residue.

Le ore residue infatti vengono tracciate sul burndown chart e danno un’indicazione quotidiana dello scostamento dalla situazione ideale in modo da poter intraprendere ogni giorno le necessarie azioni correttive.

Ovviamente le ore lavorate sono un’informazione importantissima che deve essere tracciata su sistemi elettronici di Issue Tracking, ma che non incide sulla sprint e deve essere oggetto di analisi in fase di Retrospettiva.

Share

Anatomia di una User Story card – Fronte

Nel post precedente abbiamo visto cos’è una User Story e quali sono le motivazioni che la rendono uno strumento di analisi, di condivisione delle informazioni chiave e di stimolo al confronto all’interno di un team.

Adesso voglio scendere nel dettaglio della struttura di una User Story card.

Innanzitutto un primo nota bene: una User Story raccoglie in maniera discorsiva ciò che un utente fa o vorrebbe fare nel suo lavoro quotidiano.

Una User Story Card è la rappresentazione cartacea (tipicamente in formato A6) della storia ma non solo. Raccoglie altre informazioni quali la “dimensione” della storia, i task per completarla, i test di accettazione e così via.

Ha un visibilità enorme, la si può spostare, ci si scrive sopra velocemente, sono facilmente riordinabili e confrontabili e soprattutto lo possono fare tutti. Compreso il cliente.

Non esiste LA user story card che va bene per tutti, questa è il punto di partenza che utilizzo io (fronte e retro):

User-story-frontUser-story-back

Innanzitutto una nota sulla dimensione della scheda: non deve essere troppo grande in quanto non è richiesta l’esaustività delle informazioni (per quella si va su un sistema elettronico) ma il riassunto delle informazioni fondamentali.

Partiamo dal fronte.

Titolo della User Story

Il titolo della user story serve per identificare sinteticamente e univocamente la storia.

Per esempio in un sistema di commercio elettronico può essere una frase del tipo:

  • Mario Rossi può inserire il prodotto nel carrello
  • Mario Rossi può rimuovere un prodotto dal carrello
  • Mario Rossi può svuotare completamente il carrello

Tipicamente il titolo è la descrizione sintetica con cui viene caricata nel sistema elettronico di gestione del progetto (Microsoft Team Foundation Server, Jira, OnTime, RedMine, AtTask per citarne alcuni).

Descrizione della User Story

Ricordo che la user story è un frase con questa struttura:

As Who, I want What so that Why

Continuando le storie precedenti potrebbe essere:

SONO “Mario Rossi”

e dalla pagina di dettaglio del prodotto VOGLIO inserire il prodotto nel carrello

PERCHE’ potrò avere in unico punto tutti i prodotti che vorrei acquistare

Ricordo l’aspetto essenziale: la user story deve essere scritta dal punto di vista dell’utente e utilizzando il suo linguaggio. Non c’è nulla di tecnico qui, non ci sono database, C#, o pezzi di interfaccia ma solo quello che un utente vuole fare interagendo con il sistema.

Anzi la situazione ideale è che la storia venga scritta dal cliente.

Un altro aspetto da notare è che non si parla di generico utente o cliente ma si utilizza uno specifico utente che appartiene ad una categoria che scaturisce dalla fase di user role modeling (anche di questo ne parlerò in un altro post).

In questo caso Mario Rossi è stato individuato come l’utente tipico B2C ed è chiaro a tutti quali sono le sue aspettative, le sue competenze tecniche, la sua conoscenza del dominio.

Dimensione e scadenza

La domanda scontata di fronte ad un requisito o, in questo caso, ad una User Story è: quanto ci vuole per implementarla?

Giorni? Ore? Giorni ideali? Giorni uomo? E le ferie? E i 2 membri del team che la prossima settimana devono lavorare su un altro progetto?

Il riassunto di questa e di altre informazioni “temporali” è racchiuso nel concetto di Story Point.

Genericamente si può dire che lo Story Point è una unità di misura delle User Story (al pari delle ore o dei metri) ed una misura sintetica della “dimensione della storia”.

Riesce ad essere indipendente dal tempo, non risente delle ferie o dei giorni di malattia, consente una stima molto veloce e il confronto tra le schede.

Una User Story da 8 SP è sicuramente più grande di una User Story da 5 SP. Facile, immediato e comprensibile da tutti, tecnici, commerciali, cliente.

Diventa anche il miglior metodo per fare un planning, per seguire l’andamento del progetto e per stimare e migliorare la velocità del team.

Ecco perchè DEVE essere in bella vista sul fronte della User Story Card.

Un’ultima informazione che, se presente, deve essere in primo piano è un’eventuale scadenza. Le storie entrano in una sprint in base alla priorità decisa dal Product Owner ma se c’è una scadenza ovviamente questo fa si che la storia venga selezionata per entrare in una sprint in base alla data di consegna.

Share

Le user story sono il miglior strumento di analisi che conosca

Innanzitutto cos’è una User Story?

Ovviamente partiamo dalla definizione di Wikipedia che cerco di riassumere:

“una User Story raccoglie in maniera discorsiva ciò che un utente fa o vorrebbe fare nel suo lavoro quotidiano”

E’ un insieme di frasi espresse in termini usati quotidianamente o termini di business e risponde a tre domande:

  • Who: chi fa o vorrebbe quella specifica cosa
  • What: cosa fa o cosa vorrebbe o si aspetta dal sistema
  • Why: perchè fa quella cosa o perchè la vorrebbe e quali vantaggi otterrebbe
Fisicamente la User Story è una scheda cartacea in formato A6 che riassume queste e altre informazioni fondamentali.User-Story
Il primo vantaggio che si ottiene dall’approccio tramite User Story è che obbliga i tecnici e gli sviluppatori a ragionare come l’utente finale e non immediatamente in termini di righe di codice, righe di tabelle, tecnologie, ecc ecc.
Inoltre facilita enormemente il dialogo e la comprensione con il cliente. Il cliente usa il linguaggio del dominio e siamo noi che dobbiamo adattarci al suo modo di pensare e parlare. E’ il nostro sistema che deve risolvere il suo problema ed è più facile se parliamo tutti da subito la stessa lingua (Ubiquitous Language).
Il cliente tocca la user story, la vede, la modifica e SOPRATTUTTO lo aiuta a chiarire nella sua testa che cosa vuole esattamente.
Il cliente può e deve ordinare le user story in base a ciò che per lui è prioritario (in termini economici ma non solo) e lo fa semplicemente spostando le schede.
E’ fondamentale ricordarsi che una User Story non vuole e non deve essere una analisi dettagliata di una funzionalità ma piuttosto un reminder di alcune cose che ci siamo detti e di altre che invece devono essere chiarite: la User Story stimola ed enfatizza la comunicazione verbale rispetto quello scritta.

Il fatto che venga scritta su delle schede serve anche per ottenere questo risultato in quanto le informazioni che possono essere scritte sono forzatamente limitate dallo spazio fisico della scheda.

Ovviamente maggiori informazioni possono essere raccolte in un sistema di tracking elettronico, ma ultimo ma non meno importante la user story DEVE essere cartacea perchè il suo punto di forza è l’estrema visibilità che dà alle informazioni in essa contenute.

In un altro post scenderò nei dettagli di altre informazioni più o meno tecniche che fornisce una User Story:

  • consente un confronto immediato e visivo tra le dimensioni delle storie
  • facilità la suddisivisione in storie più piccole
  • contiene la definizione dei task che servono per completare la storia
  • contiene l’elenco dei test di accettazione che servono per dire “ho finito” e dimostrano al cliente che il software fa esattamente quello che si aspetta
  • facilita il planning della release e delle sprint
  • consente di rimandare ad un momento successivo la definizione di dettagli che probabilmente oggi non abbiamo
A questo punto penso di poter dire: “Please, more user stories, less Word documents, less Power Point”
Share

Agile Coach Camp Italy 2012

Sei interessato al Coaching Agile?

Ti occupi di change management o di mentoring?Agile-Coach-camp-2012

L’Agile Coach Camp è un weekend che affronta questi temi in maniera collaborativa e autogestita con l’obiettivo di confrontarsi concretamente con chi fa questo lavoro quotidianamente.

Il camp si terrà dall’8 al 10 Giugno 2012 in trentino.

Il programma

Venerdì 8 giugno

18:00 Arrivo dei partecipanti

19:00 Cena

21:00 Evento serale

Sabato 9 giugno

9:00-18:00 Open Space

21:00 Evento serale

Domenica 10 giugno

9:00-17:00 Open Space

Tutte le informazioni sul sito ufficiale dell’evento: Agile Coach Camp Italy 2012

Share

Usare il metodo Find di Entity Framework con le chiavi composte

Il metodo Find di Entity Framework 4.3 consente di recuperare un entità dal contesto in base alla chiave primaria.

Se l’entità è già presente nel contesto viene immediatamente restituita senza nessun round-trip al server in caso contrario viene effettuata una query di SELECT sul database.

L’oggetto recuperato viene collegato al contesto. Se l’oggetto non è presente nel contesto o nel database il metodo Find restituisce null.

Ad esempio:

_dbContext.Products.Find(1);

restituisce il prodotto con chiave 1 (int)

Supponiamo adesso di avere un prodotto con chiave primaria composta (composite key):

public class Product
    {
        public string StyleCode { get; set; }
        public string MaterialCode { get; set; }
        public string ColorCode { get; set; }
    }

Il mapping sarà di questo tipo:

public ProductMap()
        {
            HasKey(product => new { product.StyleCode,
                                       product.MaterialCode,
                                       product.ColorCode });
        }

Inseriamo nel db un prodotto in questo modo:

_dbContext.Products.AddOrUpdate(p => 
new { p.MaterialCode, p.StyleCode, p.ColorCode },
                                     new Product
                                         {
                                             StyleCode = "1",
                                             MaterialCode = "2",
                                             ColorCode = "3"
                                         });

 

ed invochiamo il metodo Find in questo modo:

_dbContext.Products.Find(1, 2, 3);

Molto probabilmente il risultato sarà null.

Questo perchè la firma del metodo Find è Find(params object[] keyValues) e quindi Entity Framework a questo punto non è ancora in grado di mappare i valori della chiave nell’ordine corretto.

Il mapping della classe Product va quindi modificato utilizzando il metodo HasColumnOrder:

public ProductMap()
        {
            HasKey(product => new { product.StyleCode, 
                                       product.MaterialCode,
                                       product.ColorCode });
            Property(p => p.StyleCode).HasColumnOrder(0);
            Property(p => p.MaterialCode).HasColumnOrder(1);
            Property(p => p.ColorCode).HasColumnOrder(2);
        }

In questo modo i parametri della chiave primaria vengono mappati in ordine.

Share

Differenze tra SCRUM e Extreme Programming (XP)

Recentemente mi è stata posta questa domanda durante una presentazione dei metodi Agili: “Quali sono le differenze tra SCRUM e XP?”

Entrambi sono classificabili come “applicazioni” dei principi Agili.

La differenza principale è che SCRUM è maggiormente orientato alla gestione di un processo mentre XP è maggiormente focalizzato sugli aspetti tecnici legati allo sviluppo del software.

SCRUM è un framework di management che comprende aspetti quali il reporting, il planning, lo stato di avanzamento, la definizione degli incontri con l’obiettivo di favorire la comunicazione e avere un feedback molto rapido (al limite giornaliero) dello stato di un progetto.
releaseburndown
SCRUM cerca di ridurre al minimo l’overhead di burocrazia necessario per la gestione di un progetto e si focalizza su un processo iterativo e incrementale che porta a produrre solo ciò che serve e di maggior valore per l’azienda.

SCRUM in questo senso non è quindi strettamente legato ai processi IT ma può essere applicato con successo a qualsiasi processo aziendale.

Nell’ambito stesso di un’azienda IT si sottolinea l’importanza del fatto che SCRUM deve essere abbracciato dall’intera azienda quindi anche dal management, dai commerciali, dal marketing.

Una delle principali differenze pratiche è che SCRUM identifica una nuova figura, lo Scrum Master. Lo Scrum Master si discosta dal più classico Project Manager che definisce i task e dice chi fa cosa ma è un più generico servant-leader con questi compiti:

  • rimuovere gli impedimenti
  • assicurarsi che il processo SCRUM venga applicato correttamente
  • proteggere il Team dalle “distrazioni” (comprese le ingerenze del management e dei commerciali)

pair-programmingXP (Extreme Programming) pone invece maggiore enfasi su aspetti tecnici e pratici per lo sviluppo software.

Nel contenitore XP sono presenti tematiche quali:

  • Test-Driven Development
  • Continuous Integration
  • Pair Programming
  • Refactoring
  • Collective Ownership
  • On-site customer
  • Coding standards

Quale scegliere?

Secondo me in una azienda che sviluppa software la risposta corretta è entrambi in quanto le metodologie sono perfettamente complementari.

SCRUM da solo porterebbe sicuramente benefici in un ottica Just in time ma per raggiungere la massima efficacia e per far si che le promesse del Manifesto Agile vengano rispettate le tecniche XP si rivelano utili se non fondamentali.

All’opposto XP beneficia di SCRUM in quanto riceve un “contenitore” che garantisce il project management e l’interfaccia con il business, i commerciali ed i clienti senza troppo overhead e senza costrizioni.

Share

TeamCity 7.0 crea e distribuisce pacchetti NuGet

Sono incappato nelle release notes del nuovo TeamCity versione 7.0 rilasciato il 22 febbraio.

Solo per esclamare: NOOOO!! Quando ho letto che “Non solo TeamCity può creare dei package NuGet ma può anche fare lui stesso da server NuGet”.

Proprio oggi parlavo di TeamCity da un cliente e poi il discorso è caduto anche su NuGet e gli ho fatto notare come sia uno strumento eccezionale per distribuire dei package all’interno dell’azienda.

Pensare al connubio tra TeamCity e NuGet mi fa correre ad installarlo subito.

Share

Installare Redmine su Windows con SQLite

I requisiti per installare Redmine su Windows sono i seguenti:

  • lo stack Ruby+RubyGems+Rake+Rack
  • MySQL, PostgreSql oppure SQLlite

Per una prima installazione ho deciso di utilizzare SQLlite in modo da non dover installare un ulteriore motore di database.

Sul sito di Redmine c’è una completa guida di installazione ma in alcuni passi non è perfetta per una macchina Windows quindi li riporto di seguito.

Download di Redmine

http://www.redmine.org/projects/redmine/wiki/Download

Installare Rubyinstaller

Rubyinstallar è il package manager più diffuso per il mondo Windows.

Scaricare ed installare Rubyinstaller:

http://rubyinstaller.org/

Configurare database.yml

Copiare il file config/database.yml.example in config/database.yml

Configurare la sezione “production” per utilizzare SQLlite in questo modo:

production:
adapter: sqlite3
database: db/redmine.db
host: localhost

Installare la gemma SQLlite

Installare la gemma SQLite con il comando:

gem install sqlite3

Generare un session store

Generare un session store con il comando:

rake generate_session_store

Creare la struttura del database

Per generare la struttura del database entrare nella root directory dell’applicazione ed eseguire il comando:

rake db:migrate RAILS_ENV=production

Caricare i dati di configurazione

E’ consigliabile caricare nel database alcuni dati di configurazione di base da cui partire.

E’ sufficiente usare il comando:

rake redmine:load_default_data RAILS_ENV=production

In questo modo vengono caricati alcuni valori di default per i ruoli, i tracker, gli stati e gli enumerati.

Test dell’installazione

Installare la gemma WEBrick

gem install webrick

Lanciare il web server WEBrick

ruby script/server webrick -e production

e collegarsi all’url http://localhost:3000/

Se tutto è configurato correttamente viene visualizzata la welcome page.

Le credenziali di default sono username: admin e password: admin

NB: il webserver WEBrick non deve essere usato in produzione ma solo per le attività di testing. In un altro post vedremo come utilizzare Mongrel come servizio Windows per eseguire Redmine.

Share