marzo 2006 Entries
[OT] Ma perché non pensano al loro lavoro?

Premessa: quanto scrivo è TRASVERSALE ad ogni schieramento politico, non vuole essere una presa di posizione nei confronti dell'una o dell'altra fazione.

E' notizia di oggi che i Verdi si sono lanciati in una campagna in favore dell'open source, per sostenere il diritto del pinguino ad "uscire dalla gabbia" nella quale la corporation di Bill Gates sta cercando di rinchiuderlo.

Mi fa quantomeno sorridere il fatto che costoro dicano in giro di essere da anni in prima fila nella battaglia per la diffusione dei software e dei sistemi operativi "open source", ovvero quelli che vengono messi a punto attraverso il contributo "aperto" anche all'esterno e che l'utente non è obbligato ad acquistare a scatola chiusa, ma può tarare e adattare alle sue esigenze.

Ma per piacere... come se l'utente (anche quello esperto, eh... mica solo l'impiegato del catasto) si possa svegliare la mattina e modificare il kernel perché così la macchina ha prestazioni migliori... Se riesce ad installare Flash Player è grasso che cola! Questi sono proclami che si basano sull'ignoranza della gente, esempio palese di demagogia da quattro soldi, fatta di sparate e basta, senza alcuna base di quella cosa che risponde al nome di "informarsi".

Interessante anche la proposta di legge per introdurre Linux nelle pubbliche amministrazioni per risparmiare sul costo delle licenze, come se i sistemi server, l'assistenza, la formazione, la difficoltà maggiore nel reperire assistenza qualificata, e quant'altro ancora, non concorressero affatto al costo di un sistema informatico.

Scusate lo sfogo, ma queste cose le sopporto sempre meno.

Fonte: http://www.repubblica.it/2006/c/sezioni/politica/versoelezioni46/verdisoft/verdisoft.html

powered by IMHO 1.3

7 Comments Filed Under [ Off topic ]
Collection Master/Detail con ITypedList

Scenario: abbiamo una nostra bella custom collection, magari che implementa IBindingList, ma non siamo perfettamente soddisfatti di come il FX ne gestisca il binding: vorremmo infatti scegliere a priori, ad esempio, l'ordine con cui le proprietà vengono visualizzate quando si effettua un data binding con una DataGridView, o vorremmo poter popolare la nostra custom collection di Person anche con tipi derivati da Person (normalmente la DataGridView se la prende parecchio se ci proviamo ).

La soluzione è implementare ITypedList e io, mesi fa, l'avevo fatto seguendo i dettami di questo articolo su MSDN Magazine. E' andata sempre bene, finché oggi, facendo alcuni test sulle WindowsForms, ed in particolare provando ad implementare una semplice UI Master-Detail con BindingSource, non mi sono trovato davanti una schermata del genere:

Errore ITypedList

Prima di procedere, è necessaria una piccola premessa; l'interfaccia ITypedList è composta da due metodi, ossia:

public interface ITypedList
{
    PropertyDescriptorCollection GetItemProperties(
        PropertyDescriptor[] listAccessors);
    
    
string GetItemName(
        PropertyDescriptor[] listAccessors);
}

Il problema della soluzione proposta su MSDN Magazine è che essa non prende in considerazione il parametro listAccessors, che invece è utilizzato, ad esempio, da BindingSource tutte le volte che, assegnati DataSource e DataMember, quest'ultimo è un tipo complesso che implementa a sua volta ITypedList.

Supponiamo di avere la classe Baby che espone una collection di Toy:

public class Baby
{
    
// ... more code here ...
    
public ToyCollection Toys
    {
        
get return toys; }
    }
}

Mi piacerebbe poter visualizzare, per il bambino corrente, la griglia con l'elenco di tutti i suoi giocattoli, quindi dopo aver creato quello per il Master, creo un bel BindingSource anche per la proprietà Toy, collegato al precedente.

toysBindingSource

Cosa accade a questo punto quando la DataGridView chiede a toysBindingSource di fornire informazioni circa il tipo di dati che espone? Accade che toysBindingSource non richiama il metodo GetItemProperties di ToysCollection come ci si potrebbe aspettare, bensì richiama quello di BabyCollection, inserendo in listAccessors un PropertyDescriptor che punta alla proprietà Toys: chiede in pratica alla collection dei bambini di fornire ulteriori informazioni sul tipo restituito dalla collection dei giocattoli.

Bella grana! Noi non abbiamo il minimo riferimento per risalire a tale informazione da BabyCollection! Ho trovato in giro per la rete le soluzioni più disparate, ad esempio decorare ogni proprietà collection con un attributo che indica il tipo restituito, ma mi sembrava un'informazione ridondante e non mi piaceva granché. Allora me ne sono inventata una io :

public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors)
{
    PropertyDescriptorCollection result = 
null;

    
if (listAccessors == null || listAccessors.Length == 0)
    {
        result = TypeDescriptor.GetProperties(
typeof(T));
    }
    
else
    
{       
        PropertyDescriptor childProperty = 
          listAccessor[listAccessors.Length -1];
        
if (typeof(ITypedList)
          .IsAssignableFrom(childProperty.PropertyType))
        {
            Assembly asm = childProperty.PropertyType.Assembly;
            
object childItem =
                asm.CreateInstance(childProperty.PropertyType.FullName);

            
if (childItem != null)
            {
                ITypedList typedList = childItem 
as ITypedList;
                
if (typedList != null)
                    result = typedList.GetItemProperties(
null);
                IDisposable disposable = childItem 
as IDisposable;
                
if (disposable != null)
                    disposable.Dispose();
            }
        }
    }

    
return result;
}

Sembra complesso, ma in realtà il codice è molto semplice: nel caso listAccessors sia vuoto, restituisco tutti i tipi, come avveniva in precedenza (ho trascurato per maggiore chiarezza di implementare l'ordinamento o una selezione delle proprietà). Se invece viene richiesta, tramite  listAccessor, la descrizione di una particolare proprietà, tramite reflection richiamo il GetItemProperties della collection che questa proprietà espone.

Quanto sopra è passibile di molte migliorie: ad es. se la proprietà in oggetto non è ITypedList, il mio metodo ritorna null, ma nel mio caso specifico questo non è un problema, perché tutte le collection che uso implementano quest'interfaccia. Inoltre supporta un nesting di soli due livelli, dato che non propago listAccessors nella chiamata alla collection figlia. Francamente non ho la necessità di gestire contemporaneamente relazioni mastro/dettaglio più profonde, quindi non me ne sono preoccupato. Però penso che sia comunque un buon punto di partenza e spero che possa essere utile a qualcuno!

powered by IMHO 1.3

Add Comment Filed Under [ .Net 2.0 ]
Custom Description per le proprietà delle nostre entitity

Una delle necessità in cui si può incorrere quando si sviluppano applicazioni utilizzando custom entities, consiste nel fare in modo che le proprietà dei nostri oggetti presentino descrizioni significative una volta in binding, ad esempio, ad una DataGridView.

Personalmente cerco sempre di creare entities con nomi di proprietà significativi, ma se volessi automaticamente far apparire "Data di nascita" in luogo di "DataNascita" quando effettuo il binding di una Person? Niente di più semplice, basta utilizzare l'attributo DisplayNameAttribute :

[DisplayName("Data di nascita")]
public DateTime DataNascita
{
    
get return dataNascita; }
    
set { dataNascita = value; }
}

Ciao

powered by IMHO 1.3

3 Comments Filed Under [ .Net 2.0 ]
Possiamo fidarci del Web 2.0?

Mi ha fatto riflettere questo post che ho trovato girovagando qua e là per la rete, a proposito dei down che sembrano affliggere sempre più spesso i siti che fanno un uso spinto di AJAX. Lo stesso GMail oggi mi ha piantato in asso per la seconda volta in questa settimana, ma mi consolo perché ad altri è andata anche peggio.

Ricordo di aver letto mesi fa un post di Daniele Bochicchio pieno di dubbi su questa vecchia/nuova tecnologia, e di averlo bollato a suo tempo come "troppo pessimistico". Ad oggi non posso fare a meno di constatare quanto avesse ragione. Chapeau!

powered by IMHO 1.3

2 Comments Filed Under [ Misc ]
DataSet o Domain Model?

Oggi ho ricevuto un feedback a questo post  che mi ha dato da pensare: ultimamente mi è capitato di leggere commenti molto negativi sul modello DataSet/DataAdapter di ADO.NET, quasi che un bel Domain Model rappresenti la panacea di tutti i mali.

Il mio punto di vista, a questo proposito, è che la distinzione tra bene e male (o tra Black and White, passatemi questa... è per celebrare il successo del nostro Francesco ) non sia sempre così netta. Chi ha letto Patterns of Enterprise Application Architecture sa bene che è lo stesso Martin Fowler a sconsigliare il Domain Model in favore di altri approcci (ad es. il Table Module), nel caso di applicazioni la cui logica di business non sia complessa e soggetta a una grossa variabilità nel tempo.

Quali possono essere i punti di forza di un DataSet rispetto al Domain Model?

  • Beh.. intanto il fatto che il Table Module è direttamente mappabile sulla struttura del DB, mentre un Domain Model richiede quasi sempre un Data Mapper, che non è la cosa più facile del mondo da realizzare;
  • poi perché ci si può avvalere di generatori di codice che risparmiano parecchio lavoro (usare questi strumenti per un Domain Model, a mio modo di vedere, è un controsenso allucinante);
  • in terzo luogo perché l'integrazione del DataSet nell'IDE di Visual Studio e la struttura estremamente versatile, permettono di gestire facilmente anche strutture piuttosto complesse, che coinvolgono DataRelation e campi calcolati;
  • perché il DataSet funziona particolarmente bene con il DataBinding, implementando diverse funzionalità non banali;
  • last but not least, perché con l'accoppiata DataSet/DataAdapter ci troviamo gratis anche un bel Unit of Work e un Optimistic Offline Lock per gestire opportunamente le modifiche effettuate in locale.

Secondo me, quindi, si tratta di una scelta da ponderare con attenzione, valutando caso per caso i pro e i contro di entrambe le soluzioni. A questo proposito, per chi l'averse perso, segnalo anche un articolo del nostro Dinone nazionale su MSDN Magazine: risale a quasi un anno fa, ma quando l'ho letto mi ha fatto riflettere parecchio.

Chiudo con un'ultima considerazione, e cioé dicendo che non è scontato che Domain Model e DataSet non possano coesistere: sempre su PoEAA (pag. 206) c'è un interessante esempio di come sia possibile realizzare un Data Mapper (con tanto di lazy load) basato su DataSet e utilizzarlo per persistere le business entities.

powered by IMHO 1.3

6 Comments Filed Under [ .Net 2.0 Architettura ]
NHibernate e le collection type-safe

Una delle maggiori problematiche per chi ha avuto qualche esperienza con NHibernate è il fatto che questo O/RM non gestisce direttamente collection strongly-typed. Ammetto di non aver cercato moltissimo in giro per la rete, ma in quei 3 o 4 esempi che ho guardato, le business entities avevano sempre la forma

public class Master
{
    
// ... more code ...
    
private IList details;
    
public IList Details
    {
        
get return details; }
    }
}

Questo tipo di implementazione pone alcune problematiche: oltre al fatto di essere weakly-typed, può funzionar bene se viene utilizzata in una pagina ASP.NET, grazie al databinding poco "interattivo", ma se proviamo a collegarla ad una windows forms perdiamo un sacco di funzionalità a cui eravamo abituati usando i DataSet (il refresh dei dati sullo schermo quando aggiungiamo un elemento alla collection, tanto per dirne uno...). Non mi dilungo oltre, se non per dire che le soluzioni provate (che vanno dal tentativo di utilizzare BindingList<T>, a quanto proposto da Ayende Rahien o a quest'altra alternativa di Andrew Arnott) non mi convincono al 100%.

Per fortuna, però, non ho girovagato in rete invano : mi sono imbattuto qui, dove ho trovato un'ottima collection generic, che implementa IBindingList, e che a prima vista (dopo una lettura del codice sorgente) sembra essere addirittura migliore della BindingList<T> contenuta nel FX 2.0, dato che supporta anche sorting e find. E' molto generale e quindi può essere utilizzata anche da chi non si avvale di NHibernate, ma, in caso contrario, viene fornita anche di un accessor specifico da utilizzare nei file di mapping. Certo, non derivando da PersistentCollection FOOOORSE ha bisogno di qualche ritocco per funzionare correttamente con NHibernate, oltre al fatto che a me piacerebbe implementasse anche IComponent per poterla integrare nel designer di Visual Studio, ma credo si tratti veramente di un ottimo lavoro! Da domani proverò a metterci un po' le mani sopra...

powered by IMHO 1.3

9 Comments Filed Under [ .Net 2.0 NHibernate ]
Poi parlano male dei venerdi 17...

In realtà sono molto più temibili i Sabato 18, soprattutto quando ti viene in mente di aggiornare il tuo sistema al Framework 2.0, approfittando della giornata libera (fino ad oggi ci lavoravo su una Virtual Machine, poi l'esasperazione per la lentezza ha preso il sopravvento).

Ho già avuto piccoli sentori che qualcosa non andava quando ho disinstallato Sql Server 2000 per far posto al 2005: l'uninstall sa solo lui cosa ha eliminato, fatto sta che il servizio era ancora lì, le cartelle con tutti i programmi pure e anche le icone sul menu Start resistevano. Consiglio: mi è stata parecchio utile questa pagina del supporto Msdn, e ho domato MsSql 2000.

Passiamo a .NET e al Visual Studio: beh.... qui faccio mea culpa, ho disinstallato la versione 2003, Framework compreso, salvo poi accorgermi che RssBandit e Imho non partivano più. Fesso, dovevo guardarci prima e avrei scoperto che non giravano con .NET 2.0. Vabbè, amen, tanto metto su il Redistributable dell'1.1 e funziona tutto come prima. L'installazione di VS2005 fila liscia, con mia somma sorpresa, visto che tempo fa avevo messo su la Beta2 e avevo notizie di parecchi problemi di installazione della versione definitiva di Visual Studio. Sto quasi per stupirmi della mia fortuna, mentre avvio il setup di Sql Server 2005, quando mi becco un paio di errori tipo "Could not load assembly blablabla.." e "Microsoft Visual Studio needs to be restarted"

Scelgo di continuare e l'installazione termina, incredibilmente degli errori nessuna traccia neanche nel log, SQL Server pare funzionare e anche Visual Studio. Ora mi resta solo da capire come mai un paio di applicazioni web che funzionavano nella Virtual Machine, ora mi fanno apparire un bel "Server Application Unavailable" tutto rosso, mentre progetti nuovi sembrano girare tranquillamente.

Torno a lottare...

powered by IMHO 1.3

2 Comments Filed Under [ .Net 2.0 Off topic ]
E' arrivato!!

Finalmente oggi il postino mi ha consegnato CLR via C# di Jeffrey Richter. Bene bene! Sono proprio curioso di leggerlo. Da stasera inizio a papparmelo

powered by IMHO 1.3

3 Comments Filed Under [ Libri ]
[Forse OT] Una domanda a cui non so dare una risposta

Perché quando si prova a consigliare ai propri superiori di utilizzare un RDBMS come SQL Server 2005 in luogo di FireBird, "tanto la Express va bene alla maggioranza dei nostri clienti ed è anche gratuita" o si prova a dire che "Visual Studio 2005 e il .NET 2.0 (anzi, la tecnologia .NET in generale) risolvono parecchie problematiche con cui quotidianamente ci troviamo ad avere a che fare", si viene bollati come "Microsoftiani"?

powered by IMHO 1.3

8 Comments Filed Under [ Off topic ]
Anche i libri vanno in beta

Mi ha incuriosito parecchio un post di ScottGu in cui è citata una nuova iniziativa della casa editrice americana O'Reilly, che già annovera nel proprio catalogo parecchi titoli interessanti, ad esempio questo su WPF di Chris Sells (inutile dire che è nella mia wish list già da un paio di mesi ). Ok, come al solito mi son perso in chiacchiere, dicevo... la nuova iniziativa...

Beh, il nome è Rough Cuts e mi è parsa sinceramente un'idea ingegnosa: oggi pago e ho la possibilità di accedere alle varie revisioni di un libro, in PDF, prima ancora che questo venga stampato; eventualmente, poi, posso acquistarne la versione cartacea nel momento in cui questa sarà disponibile (o tutto in un unico bundle). E' un sistema che funziona particolarmente bene nel caso di tecnologie ancora in fase di sviluppo (c'è, in catalogo, un libro interessantissimo su Atlas, ad esempio, credo che lo prenderò), dato che al variare di esse si rendono ovviamente necessari continui editing al testo.

Niente male come idea, e se piace a ScottGu...

powered by IMHO 1.3

Add Comment Filed Under [ Libri ASP.NET 2.0 ]
Il mio weekend

Igor mi ha tolto le parole di bocca (o, per meglio dire, i caratteri dalla tastiera ) : anche io stavo per scrivere qualcosina a proposito di un weekend parecchio "object-oriented", trascorso tra C# e NUnit.

Parecchio tempo l'ho passato integrando il ValidationApplicationBlock di Andrea. Che dire... beh, innanzi tutto che effettivamente questa storia dei custom attributes, che ha visto nascere un enorme secondo post addirittura all'una di notte passata, mi sta prendendo fin troppo la mano!  Ho modificato un paio di cosine delle classi già presenti e inserito alcune nuove funzionalità, speriamo che Andrea gradisca, così magari ve le ritrovate in una prossima release!

In ogni modo, di una cosa sono certo: e cioé che metter mano al codice scritto da altri sia un'esperienza enormemente formativa! Nel mio caso, ad esempio, mi sono assolutamente convinto dell'importanza dello Unit Testing. Ricordo che in passato avevo seguito un webcast sull'argomento proprio di Andrea, ma ammetto di aver sempre snobbato quest'aspetto dello sviluppo. Bene, ciò che ho imparato è che ci si accorge di quanto sia importante un tool come NUnit  la prima volta che si trova a fare del refactoring. Infatti, se siamo bravi a scrivere TestFixture significativi, basta un click sul pulsante Run di NUnit e un verde generale nella barra di risposta, per essere ragionevolmente sicuri che tutto continui a funzionare come prima. Se solo penso a quante verifiche ero abituato a fare in precedenza e, soprattutto, a quanto tempo ho perso alle prese con queste, beh... mi vien quasi da mangiarmi le mani!

Ah... tra le varie cose, sono andato al cinema a vedere Capote - A sangue freddo. Veramente un gran bel film, anche se forse non per tutti, con un Philip Seymour Hoffman in gran forma che ha dimostrato di meritare fino in fondo l'Oscar che ha recentemente vinto.

powered by IMHO 1.3

3 Comments Filed Under [ .Net 2.0 Off topic ]
La mia piccola biblioteca cresce

Non ho resistito al colpo, la comunicazione di Amazon del ritardo di ASP.NET 2.0: Advanced Topics l'ho presa male . Ma siccome chiodo schiaccia chiodo, ho ordinato al volo il nuovo CLR Via C#: Applied .NET Framework 2.0 Programming di Jeffrey Richter. Non ho letto il suo lavoro precedente, ma ne ho sentito parlare come una sorta di Bibbia che ogni sviluppatore dovrebbe avere nella propria biblioteca personale.

Sicuramente anche questo sarà dello stesso livello, non vedo l'ora che arrivi (dovrebbe essere qui per la prossima settimana) per buttarmi nello studio di cosa accade dietro le quinte del CLR. Poi vi faccio sapere com'è!

powered by IMHO 1.3

2 Comments Filed Under [ Libri ]
Ancora su custom attributes e validazione

In un post precedente ho iniziato un discorso su come utilizzare le potenzialità dei custom attributes per validare le nostre entity. Una volta capito il meccanismo, è estrememente semplice implementare tutta una serie di classi che permettano le più disparate tipologie di validazioni, magari anche combinandole tra di loro.

Il nostro nuovo ErrorMessageAttribute

Ma se la validazione fallisce come dobbiamo comportarci? Beh, l'ideale a questo punto sarebbe sollevare un'eccezione, magari potendo fornire un messaggio d'errore specifico per il membro che non è stato correttamente valorizzato. Siccome ci stiamo appassionando tantissimo alla programmazione dichiarativa , realizziamo un bell'attributo simile a questo (semplicissimo) che segue:

public class ErrorMessageAttribute: Attribute
{
    
private string errorMessage;
    
public string ErrorMessage
    {
        
get return errorMessage; }
    }
    
    
public ErrorMessageAttribute(string message)
    {
        
this.errorMessage = message;
    }
}

In questo modo possiamo scrivere qualcosa come:

public class AdultPerson: Person
{
    
//... more code ....
    
private int age;
    
    [MinValue(18), ErrorMessage("E' necessario che l'individuo sia maggiorenne!")]
    
public int Age
    {
        
get return age; }
        
set { age = value; }
    }
    
    
//... more code ....
}

e con una minima modifica al metodo di validazione, che non inserisco qui per non dilungarmi ulteriormente ma che è abbastanza banale (altrimenti chiedete pure lumi), si può recuperare il messaggio di errore da questo attributo. Benissimo, ma se volessimo supportare anche la localization in diverse lingue?

Facciamo diventare ErrorMessageAttribute anche localizzabile

Beh, intanto iniziamo con una premessa: quanto scritto poc'anzi non è una pratica correttissima, dato che le stringhe andrebbero sempre memorizzate in un resource file e richiamate tramite un resource manager (FxCop si arrabbia tantissimo per questo ). Allo scopo sono solito implementare, in ogni assembly che lo richieda, una classe Singleton che instanzia un ResourceManager e restituisce le stringhe tramite un metodo statico che legge il file di risorse della culture corrente (ah, dimenticavo, questo è esattamente quanto accade nelle classi del .NET Framework, parola di Reflector). Un piccolo snippet per spiegare quanto detto:

internal sealed class Res
{
    
private ResourceManager resource;      
    
private Res()
    { 
        
this.resource =
          
new ResourceManager("ResourcesName", Assembly.GetExecutingAssembly());   
    }   
        
    
// Singleton semplificato. Attenzione, NON E' THREAD-SAFE
    
private static Res _defaultInstance;
    
private static Res defaultInstance
    {
        
get
        
{
            
if (_defaultInstance == null)
              _defaultInstance = 
new Res();
            
return _defaultInstance;
        }
    }
    
    
// questo è il metodo che recupera la risorsa string
    
public static string GetString(string name)
    {
        Res instance = Res.getDefaultInstance();
        
        
return instance.resource.GetString(name);
    }
}

Con i custom attributes, però, la faccenda si complica un po', dato che i parametri che possiamo fornire ai costruttori possono essere solo costanti, type, o array degli stessi. In pratica il codice seguente

[MinValue(18), ErrorMessage(Res.GetString("InvalidAge"))]
public int Age
// ....

non compila. Una possibile soluzione, allora, è creare un nuovo costruttore di ErrorMessageAttribute a cui passare il type del nostro Res e il nome della risorsa string da cercare:

public ErrorMessageAttribute(Type staticResourceManager, string resourceName)
{
    MethodInfo method = staticResourceManager
        .GetMethod("GetString", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
    
    
if (method != null)
        
this.errorMessage = (string)
            method.Invoke(
nullnew object[] { resourceName });
}

Tramite Reflection, il costruttore ispeziona il tipo passato come parametro e cerca un metodo statico di nome GetString simile a quello che abbiamo scritto in precedenza. Per utilizzarlo basta scrivere

[MinValue(18), ErrorMessage(typeof(Res), "InvalidAge")]
public int Age
// ....

e i nostri messaggi d'errore divengono automaticamente localizzabili, a patto di creare un file di risorse per ogni culture che vogliamo supportare.  L'unico lato negativo di questa implementazione (e purtroppo non di poco conto) è che la chiamata a Res non è strong-typed e se commettiamo qualche errore, ad esempio rinominando GetString in GetStringa, ce ne accorgiamo solo a run-time. Sinceramente non mi è venuta in mente una soluzione migliore, quindi sono aperto a tutti i consigli possibili!

Ciao!

powered by IMHO 1.3

Add Comment Filed Under [ .Net 2.0 ]
ASP.NET 2.0 Advanced Topics in ritardo...

Ho appena ricevuto una mail da Amazon UK con cui mi si avverte che ci vorranno tra le 3 e le 5 settimane di ulteriore attesa per avere il prossimo libro di Dino Esposito, Programming Microsoft ASP.NET 2.0 Applications: Advanced Topics, che avevo preordinato già da un mesetto.

Uff... e io che stavo divorando il Core Reference per terminarlo entro la metà di questo mese

powered by IMHO 1.3

Add Comment Filed Under [ Libri ASP.NET 2.0 ]
Avete idee da proporre per il prossimo Visual Studio?

Se siete utilizzatori abituali di Visual Studio 2005, allora consiglio di dare un'occhiata a questo post di Brian Goldfarb: c'è infatti la possibilità di partecipare al nuovo programma denominato Engineer-to-Engineer per fornire feedback sulla nostra esperienza di tutti i giorni con l'IDE di Microsoft. Qual è il premio per il disturbo? Beh, ogni volta che si viene contattati, ci sarà la possibilità di scegliere un regalo tra una serie di software gratuiti che vanno da giochi XBox a Visual Studio Professional.

powered by IMHO 1.3

Add Comment Filed Under [ Visual Studio ]
Design Templates gratuiti da Microsoft

Magari per tanti di voi sarà già tutto noto, ma lo scrivo lo stesso per chi, come me, non ne era al corrente.

Sul sito di MSDN, e più precisamente a questo indirizzo, sono presenti diversi template da utilizzare per le nostre web-apps. Alcuni sono veramente carini e, cosa importante anche per "fini didattici", sono tutti realizzati sfruttando parecchie delle novità di ASP.NET 2.0, quali Master Pages, GridView, Themes, ecc.ecc.

Buon download

powered by IMHO 1.3

Add Comment Filed Under [ .Net 2.0 ASP.NET 2.0 ]
Un custom attribute per la validazione

Ieri sera, mentre riscrivevo alcune delle baseclass del mio domain model sfruttando alcune delle chicche del FX 2.0 (leggi BindingList<T>, che mi fa risparmiare un sacco di codice), mi sono chiesto se non fosse possibile costruire una struttura per validare automaticamente le mie business entities, visto che il codice da scrivere è spesso ripetitivo: questa proprietà non può essere nulla, quest'altra deve essere maggiore di zero, e così via.

In pratica, ciò che si vuol fare è di integrare i metadati delle nostre classi decorandole con Attributi personalizzati che poi possiamo recuperare a runtime via reflection. Supponiamo, ad esempio, di voler realizzare un RequiredAttribute per indicare che una certa proprietà non può assumere valore null:

[AttributeUsage(AttributeTargets.Property, AllowMultiple=false)]
public class RequiredAttribute: Attribute
{
    
public RequiredAttribute() { }
    
    
public bool IsValid(PropertyInfo property, object objectToValidate)
    {
        
object value = property.GetValue(objectToValidate);
        
if (value == null)
            
return false;
        
        
if ((value is string) && ((stringvalue).Length == 0)
            
return false;
        
        
return true;
    }
}

La primissima riga è un attributo da applicare alla nostra classe per indicare che un RequiredAttribute (e mai più di uno) sarà applicabile solo ad una proprietà (non ad assembly o a classi, ad esempio, non avrebbe alcun senso!), pena un errore di compilazione. Ciò che poi dobbiamo fare è solo creare una classe che erediti da System.Attribute, dotarla di un costruttore ed eventualmente di proprietà/metodi. Nel mio caso specifico, essendo RequiredAttribute molto semplice, non ho bisogno di proprietà aggiuntive, ma solo di un metodo che effettui la validazione.

Come usiamo il nostro attributo nuovo di zecca? Beh, ad esempio...

public class Person
{
    
private string firstName;
    [Required()]
    
public string FirstName
    {
        
get return firstName; }
        
set { firstName = value; }
    }
    
    
// .... codice .....
    
    
public void Validate()
    {
        
foreach(PropertyInfo property in this.GetType().GetProperties())
        {
            RequiredAttribute attr = property.GetCustomAttribute(
                property, 
typeof(RequiredAttribute));
            
if (attr != null && !attr.IsValid(property, this))
                
throw new Exception(string.Format(
                    "Errore: la proprietà {0} non può essere vuota!",
                    property.Name));
        }
    }
}

Nel metodo Validate(), tramite reflection, si cicla per tutte le proprietà che appartengono alla classe Person. Nel caso in cui queste siano decorate da un RequiredAttribute, se ne richiama il metodo IsValid per verificarne la correttezza.

Ora, sono d'accordo che quanto scritto sino ad ora possa sembrare un'inutile complicazione, ce la saremmo potuta benissimo cavare con un

if (FirstName == null || FirstName.Length == 0) then
  
throw new Exception(...);

Qual è allora il vantaggio di quest'approccio dichiarativo? Beh, innanzitutto si può implementare il metodo Validate in una classe base da cui ereditano tutti gli oggetti del Domain Model, in modo da poter verificare la corretta valorizzazione delle proprietà obbligatorie semplicemente decorandole con [Required()]. Inoltre nulla vieta di realizzare custom attributes di validazione più complessi, che verifichino ad esempio che il valore di una proprietà cada entro un certo intervallo, che soddisfi una certa regular expression o addirittura demandarne la validazione ad una porzione di codice custom. Se è interessante, magari riprenderò il discorso in un prossimo post.

Per chi volesse comunque approfondire, segnalo questa pagina della MSDN Library e quest'articolo di Ted Pattison su MSDN Magazine.

powered by IMHO 1.3

4 Comments Filed Under [ .Net 2.0 ]
Build a program now!

Scaricando uno qualsiasi dei Visual Studio Express Edition e registrandosi, si ottiene gratuitamente tutta una serie di download aggiuntivi, alcune icone, immagini e i libri (ovviamente in formato PDF) della serie Build a program NOW!

Ho avuto l'occasione di dare un'occhiata a questi ultimi qualche giorno fa, dopo che mio padre mi aveva chiesto una guida semplice per realizzare qualche piccola applicazione su windows. Che dire... mi hanno sorpreso, veramente un ottimo lavoro: coprono un'ampia fascia di argomenti, che vanno dal making-up delle interfacce alla validazione dell'input dell'utente, o dalla gestione dati tramite un RDBMS fino ai WebServices, spiegando piuttosto nel dettaglio parecchi aspetti della programmazione OO (incapsulamento, ereditarietà, override, ecc.ecc.), e tutto ciò realizzando passo passo programmini anche molto accattivanti, quali un bel web browser o un utility che si posiziona nel Systray e ci aggiorna sulle previsioni meteo. Il tutto per oltre 250 pagine a colori, piene di immagini e, soprattutto GRATIS.

Non ho ancora guardato la guida per il Web, magari questa sera vi dirò qualcos'altro.

In ogni caso, che dire... Proprio niente male, bella lì! ;)

powered by IMHO 1.3

Add Comment Filed Under [ .Net 2.0 Libri ]
Application.Run(new Ugiblog());

Alla fine mi sono deciso anch'io! Da troppo tempo me ne stavo in un angolino intimidito dai guru che girano da queste parti, pian piano ho iniziato a scrivere qualcosina sul forum e poi ho maturato l'idea di sfruttare lo spazio che UGIdotNet ci mette a disposizione per scrivere qualcosina di mio.

Sono Marco e vivo in Abruzzo, dove lavoro in un'azienda che sviluppa software per le PA (putroppo in Delphi, per questo il mio tempo libero si divide tra la fidanzata e .NET ;) ). Spero proprio di riuscire a scrivere qualcosa di interessante su queste pagine, e confido di imparare anche tantissimo da questa esperienza!

A presto!

powered by IMHO 1.3

8 Comments Filed Under [ Off topic ]