di .NET e di altre amenità

Entity Framework 4.0: Due webcast su Be-It

La scorsa settimana sono stati pubblicati due webcast su be-it - il sito di video di Microsoft Italia - che ho registrato recentemente. L'argomento è l'Entity Framework 4.0, che è stato rilasciato recentemente all'interno del Framework 4.0. I webcast sono i seguenti:

  1. Entity Framework 4.0: Introduzione
  2. Entity Framework 4.0: Le novità

Sono particolarmente contento del primo che è una semplice introduzione agli ORM, realizzata con poche slide animate per raccontare le problematiche dell'object realtional mapping attraverso la lente di Entity Framework. I vostri commenti su cosa migliorare sono ben accetti ovvaimente.

Resharper 4.0: Una strana politica nei "var"

Sto provando Resharper 4.0 da qualche giorno e come al solito lo trovo uno strumento utile e ben fatto che come dalla versione 3.0 è anche finalmente "delicato" nell'uso delle risorse della macchina e di conseguenza maggiormente usabile.

Quello che mi ha un po' indispettito è l'abitudine di Resharper di suggerire l'uso indiscriminato della keyword "var". E' pur vero che questo non ha alcun impatto nell'applicazione, ma la leggibilità del codice ne perde e anche parecchio. Perciò a mio parere la prima cosa da fare non appena installato Resharper è di recarsi nelle opzioni e sotto Code Inspection > Inspection Severity disabilitare le ultime due opzioni della sezione Code redundancies in particolare quelle che recitano:

  • Use 'var' keyword when initializer explicitly declares type
  • Use 'var' keyword when possible

Un bel "Do not show" a queste opzioni ricondurra Resharper alla ragione e ci lascerà scrivere il codice così come si dovrebbe fare cioe esplicitando il tipo ovunque possibile. A mio parere l'uso della keyword 'var' è legittimo esclusivamente quando abbiamo a che fare con degli anonymous types. Ogni altro uso è sostanzialmente uan illegittima scorciatoia.

Technorati Tags: ,

XeDotNet: Prossimi appuntamenti

Le due settimane che sono iniziare ieri sono dense di appuntamenti per il nostro gruppo e ci aspettano ben due eventi GRATUITI che si terranno il 16 e il 29 Maggio.

Un appuntamento da non perdere per tenersi aggiornati sulla piattaforma Microsoft per lo sviluppo su web. Andrea Dottor infatti oltre a mostrare alcune delle feature di ASP.NET 3.5 mostrerà anche una preview di alcuni dei controlli rilasciti nella recente beta della Service Pack 1. Inizio ore 19:00 - leggi >>

Organizzato in collaborazione con 1NN0va, si tratta di un evento ad ampio spettro dedicato agli sviluppatori web. Oltre ad ASP.NET 3.5 vedremo anche Silverlight 2.0 e Windows Communication Foundation 3.5. Gli argomenti saranno esposti da me (Silverlight 2.0). Andrea Dottor (ASP.NET 3.5) e Davide Bedin (WCF). Inizio ore 18:00 - leggi >>

Vi consiglio di prenotare il vostro posto in prima fila al più presto perchè ormai siamo agli sgoccioli.

Disponibile la Beta 1 del Framework 3.5 SP1

Ieri nel tardo pomeriggio è stata annunciata la prima beta pubblica della Service Pack 1 del Framework 3.5. Ci era stata annunciata durante il Global Summit, e puntualmente ne da notizia sul suo weblog, assieme ad altri blogger Microsoft.

La Service Pack in questione in realtà a prima vista da l'impressione di essere una nuova release del Framework stesso tante sono le cose nuove che include:

  • ASP.NET Dynamic Data
  • System.Web.Routing
  • Vari miglioramenti all'intellisense
  • Vari miglioramenti sullo sviluppo client
  • Windows Forms Controls
  • Notevoli miglioramenti per WPF
  • ADO.NET Entity Framework and LINQ to Entities
  • ADO.NET Data Services

Ormai il confine tra Service Pack e nuova release è talmente sottile da risultare invisibile. Tanto valeva dare una versione 3.6 e rilasciare un nuovo Framework!

Beh, pazienza...

Link: http://weblogs.asp.net/scottgu/archive/2008/05/12/visual-studio-2008-and-net-framework-3-5-service-pack-1-beta.aspx

NotSupportedException sul metodo SqlDataRecord.SetChar

Un collega sta lavorando per realizzare alcune stored procedure usando il CLR per risolvere delle esigenze un po' complesse nell'estrarre le informazioni. Poco fa si è imbattuto in una curiosa situazione. Chiamando il metodo SetChar dell'oggetto SqlDataRecord si ottiene un inspiegabile NotSupportedException. Sulle prime il collega credeva di aver sbagliato qualcosa infatti andando a leggere la pare che tutto debba funzionare a dovere. Ma... con il buon Reflector alla mano si vede immediatamente che in effetti il metodo non è supportato:

   1: public virtual void SetChar(int ordinal, char value)
   2: {
   3:     this.EnsureSubclassOverride();
   4:     throw ADP.NotSupported();
   5: }
   6:  

E' evidente che si tratta di un errore nella documentazione. La soluzione in questo caso è di usare il metodo che è un po' più laborioso ma alla fine fa bene il suo dovere.

Rilasciato il Training Kit di .NET 3.5 enhancements

E' stato rilasciato un training kit relativo i futuri "enhancements" del Framework 3.5. Si tratta di un pacchetto di hands-on-lab che comprende le seguenti tecnologie:

  • ADO.NET Data Services
  • ADO.NET Entity Framework
  • ASP.NET AJAX History
  • ASP.NET Dynamic Data
  • ASP.NET MVC
  • ASP.NET Silverlight controls
  • Per maggiori dettagli leggete questo post:

    http://lostintangent.com/2008/04/16/net-35-enhancements-training-kit/

    Il download pubblico lo trovate qui:

    http://www.microsoft.com/downloads/details.aspx?FamilyID=355c80e9-fde0-4812-98b5-8a03f5874e96&displaylang=en

    WCF Mobile: Deserializzare un FaultMessage con CF 3.5

    Il nuovo Microsoft .NET Compact Framework 3.5 ha introdotto la possibilità di consumare servizi WCF da dispositivi mobili. Naturalmente come ci si può attendere ci sono svariate limitazioni nel farlo, ad esempio l'uso esclusivo del BasicHttpBinding (l'equivalente del vecchio ASMX), l'impossibilità di usare la Session e altre cose.

    Tra queste limitazioni c'è anche la mancata deserializzazione delle FaultException che arrivano dalle eccezioni sollevate sul server. In effetti se si va a vedere nella proprietà FaultMessage dell'oggetto CFFaultException che viene autogenerato dal netcfsvcutil.exe si trova uno spezzone di xml che rappresenta la porzione del messaggio SOAP che contiene i dettagli del Fault. Dato che è utile poter leggere informazioni queli la FaultString o lo StackTrace mi sono fatto un paio di classine che deserializzano il messaggio su piattaforma CF 3.5 e lo trasformano nell'istanza di una classe. Ecco qui di seguito le classine:

       1: // CORPO DEL MESSAGGIO
       2:  
       3: [XmlRoot("Fault", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
       4: public class ServiceFault
       5: {
       6:     public static readonly ServiceFault Empty = new ServiceFault() { FaultString = "No Fault" };
       7:  
       8:     public ServiceFault()
       9:     {
      10:         this.Detail = new List<ServiceFaultDetail>();
      11:     }
      12:  
      13:     [XmlElement("faultcode", Namespace = "")]
      14:     public string FaultCode { get; set; }
      15:     [XmlElement("faultstring", Namespace = "")]
      16:     public string FaultString { get; set; }
      17:     [XmlArray("detail", Namespace = "")]
      18:     [XmlArrayItem(typeof(ServiceFaultDetail), Namespace = "http://schemas.datacontract.org/2004/07/System.ServiceModel")]
      19:     public List<ServiceFaultDetail> Detail { get; set; }
      20: }
      21:  
      22: // DETTAGLI DELL'ECCEZIONE
      23:  
      24: [XmlType(TypeName = "ExceptionDetail")]
      25: public class ServiceFaultDetail
      26: {
      27:     public ServiceFaultDetail()
      28:     { }
      29:  
      30:     [XmlElement("Message", Namespace = "http://schemas.datacontract.org/2004/07/System.ServiceModel")]
      31:     public string Message { get; set; }
      32:     [XmlElement("StackTrace", Namespace = "http://schemas.datacontract.org/2004/07/System.ServiceModel")]
      33:     public string StackTrace { get; set; }
      34:     [XmlElement("Type", Namespace = "http://schemas.datacontract.org/2004/07/System.ServiceModel")]
      35:     public string Type { get; set; }
      36: }

    Una cosa evidente è la presenza di molti namespace che in effetti hanno reso la realizzazione della classe un po' difficile. Basti pensare che se date in pasto a xsd.exe l'xml del FaultMessage vi creerà correttamente l'xsd ma poi da questo non sarà in grado di scrivere la classe che lo deserializza. In seguito per comodità mi sono scritto anche una classe di supporto che mi fa la deserializzazione (e anche la serializzazione casomai servisse...) e ve la riporto in toto:

       1: public static class FaultSerializer
       2: {
       3:     /// <summary>
       4:     /// Deserializes the specified fault.
       5:     /// </summary>
       6:     /// <param name="fault">The fault.</param>
       7:     /// <returns></returns>
       8:     public static ServiceFault Deserialize(CFFaultException fault)
       9:     {
      10:         if (fault == null)
      11:             throw new ArgumentNullException("fault", "f ault cannot be null");
      12:         if (string.IsNullOrEmpty(fault.FaultMessage))
      13:             return ServiceFault.Empty;
      14:  
      15:         string xml = fault.FaultMessage;
      16:  
      17:         using (StringReader reader = new StringReader(xml))
      18:         {
      19:             XmlSerializer serializer = new XmlSerializer(typeof(ServiceFault), "http://schemas.xmlsoap.org/soap/envelope/");
      20:             return serializer.Deserialize(reader) as ServiceFault;
      21:         }
      22:     }
      23:  
      24:     /// <summary>
      25:     /// Serializes the specified fault.
      26:     /// </summary>
      27:     /// <param name="fault">The fault.</param>
      28:     /// <returns></returns>
      29:     public static string Serialize(ServiceFault fault)
      30:     {
      31:         StringBuilder builder = new StringBuilder();
      32:  
      33:         using (StringWriter writer = new StringWriter(builder))
      34:         {
      35:             XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
      36:             ns.Add("s", "http://schemas.xmlsoap.org/soap/envelope/");
      37:             ns.Add("i", "http://www.w3.org/2001/XMLSchema-instance");
      38:             ns.Add("a", "http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher");
      39:  
      40:             XmlSerializer serializer = new XmlSerializer(fault.GetType(), "http://schemas.xmlsoap.org/soap/envelope/");
      41:             serializer.Serialize(writer, fault, ns);
      42:         }
      43:  
      44:         return builder.ToString();
      45:     }
      46: }

    Anche in questo caso è necessario fare molta attenzione ai namespace. Nella classe ServiceFaultDetail ho volutamente "scartato" le proprietà HelpLink e InnerException perchè al momento a me non servono e mi avrebbero richiesto un po' lavoro aggiuntivo. Credo comunque che implementare anche questa parte non sia poi così complesso.

    Un grazie a per il prezioso aiuto nel districare i namespace...

    Il saggio dice: non fidarti della documentazione in italiano

    Da tempo immemore vado spiegando a colleghi, amici e persone che conosco che fare uso della documentazione in lingua italiana è solo uno dei tanti modi di esprimere un malsano masochismo. Oggi ho avuto l'ennesima dimostrazione di questo concetto nel cercare di chiarirmi le idee su come funziona l'algoritmo di calcolo dell'hash in GetHashCode(). Nella documentazione italiana si legge:

    Se due oggetti dello stesso tipo rappresentano lo stesso valore, la funzione hash deve restituire lo stesso valore di costante per entrambi gli oggetti.

    Oserei dire semplice conciso ed efficace. Purtroppo quello che leggete è esatto, ma talmente incompleto da risultare errato. Ecco come appare lo stesso punto della documentazione in inglese:

    If two objects compare as equal, the GetHashCode method for each object must return the same value. However, if two objects do not compare as equal, the GetHashCode methods for the two object do not have to return different values.

    Ora se non fosse abbastanza chiaro ecco la giusta traduzione in lingua italiana del medesimo concetto:

    Se due oggetti dello stesso tipo rappresentano lo stesso valore, GetHashCode() deve restituite lo stesso risultato per entrambi gli oggetti. Tuttavia se due oggetti non rappresentano lo stesso valore il metodo GetHashCode() non deve necessariamente restituire risultati diversi.

    Può sembrare una sottigliezza, ma se ci pensate la differenza è abissale. Nel primo caso potete fare affidamento che ol metodo restituisca hash sempre diversi, mentre nel secondo assolutamente no.

    Offerta di Lavoro #2

    L'azienda presso cui lavoro ricerca 2 figure professionali da inserire nel proprio organico. Le figure ricercate sono le seguenti:

    1. Programmatore con competenze specifiche di DataBase Sql Server 2005, e buona conoscenza di C# 2.0 e del Framework 2.0 o superiori.
    2. Programmatore con competenze specifiche dello sviluppo su piattaforma Mobile (Windows CE, Windows Mobile 5.0 o superiori). Sono richieste capacità di sviluppo con Compact Framework 2.0 o superiore, e C++ sempre su piattaforma Mobile.

    Per entrambe le figure si richiede la predisposizione al lavoro in team, e buona capacità analitica.

    Per informazioni scrivere nei contatti o al messenger.

    Azienda cerca programmatore ASP.NET

    Una azienda di Cittadella (PD) mi ha chiesto il riferimento di qualche programmatore web da selezionare per il proprio organico. Sono richieste conoscenze ASP.NET, C# e Sql Server. Costituisce titolo preferenziale la conoscenza del CMS Umbraco.

    Chi fosse interessato mi scriva nei contatti o al messenger.

    OggSync: Sincronizzare Google Calendar con Windows Mobile

    Era un po' di tempo che cercavo qualcosa di simile, ed ero quasi giunto alla conclusione di dover acquistare un account di Exchange e trasferire tutto (posta e calendari) su di esso. Oggi, ho finalmente trovato , una bella applicazione la cui versione base è freeware che mi consente di sincronizzare direttamente il calendario di Google con il mio PDA attraveso internet o via ActiveSync. L'applicazione fa uso del Compact Framework 2.0 e dalle prime prove che ho fatto sembra fatta proprio bene. Ora la proverò per qualche giorno e se fa al caso mio potrei anche investire i 30$ annui per la versione pro, sempre che ne senta il bisogno.

    Download e info:

    Technorati Tag: , ,

    ASP.NET: Uno extension method per trovare i controlli

    Da qualche tempo in rete proliferano gli Extension Methods. Lo stesso Scott Guthrie in un suo recente ne ha presentato uno, e qualcun altro ne ha preparato addirittura una . Queste utili estensioni che tipicamente si applicano ai tipi del Framework per estendere le funzionalità, aggiungendo magari qualcosa che chi ha progettato una classe non poteva certo prevedere.

    Questo cappello serve ad introdurre il mio contributo a questa moda... :). Pochi minuti fa, mentre portavo un po' di codice verso il Framework 3.5, m'è venuto in mente di trasformare un in Extension Method. Il bello è che il "porting" ho richiesto la semplice introduzione della parola chiave "this" davanti al primo parametro, quindi non più di 30 secondi netti considerando anche il refactoring delle due posizioni in cui il metodo era usato e un misunderstanding con l'intellisense di Resharper che ancora non li supporta. Ecco il risultato:

    public static class ControlUtil { /// <summary> /// Finds the control recursive. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="root">The root.</param> /// <param name="id">The id.</param> /// <returns></returns> public static T FindControlRecursive<T>(this Control root, string id) where T : Control { if (root.ID == id && root is T) return root as T; if (root.HasControls()) { foreach (Control child in root.Controls) { T foundControl = FindControlRecursive<T>(child, id); if (foundControl != null) return foundControl; } } return default(T); } }

    Il "this" in questione è quello situato davanti al primo parametro del metodo che conferisce ad esso la capacità di essere usato anche come Extension Method (l'uso consueto rimane sempre possibile però...).

    Ora, scritto questo e compilato referenziando l'assembly System.Core.dll, diventa possibile scrivere qualcosa del genere:

    ... public partial class DefaultPage : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { TextBox txtCode = this.FindControlRecursive<TextBox>("txtCode"); } } ...

    In pratica con gli Extension Methods è possibile avere il meglio della programmazione Object Oriented, ma anche la possibilità di estendere le classi create da altri senza per questo violare il principio dell'incapsulamento... Parafrasando un noto spot pubblicitario si potrebbe dire: "è come avere la moglie che dice sempre sì..."

    Sto bene... Sto Benissimo!!!

    Technorati tags: , ,