in

dotNet Umbria [DNU]

Il primo User Group in Umbria sul mondo .Net

Paolo Possanzini

  • WPF 4: Sviluppare interfacce di nuova generazione ..... un piccolo assaggio....

    WPF ci permette di sviluppare applicazioni sempre più complesse (anche graficamente) e ci permette di esplorare nuove forme di interazione con l'utente.
    In più ogni giorno, o quasi, sentiamo parlare di nuovi dispositivi che ci permettono di fare cose fino a poco tempo fa soltanto immaginabili.

    Basta pensare a tutti i dispositivi touch, alla possibilità di interagire con cellulari, palmari, televisioni in modo sempre nuovo e sempre diverso.
    Ma quali sono gli strumenti che possiamo utilizzare per sviluppare le applicazione rimanendo al passo con le nuove tecnologie e con i nuovi dispositivi ?

    Posso immaginare che a breve inizieremo a vedere dispositivi multitouch anche su PC di basso profilo, sui portatili e sulle TV di casa.

    Come possiamo sviluppare le nostre applicazioni in modo da utilizzare questa nuova generazione di dispositivi a nostro vantaggio,
    con il solo scopo di migliorare l'interazione con l'utente, rendere il nostro software più facile da utilizzare e più accattivante ?

    WPF 4.0 e Windows 7 in realtà ci mettono a disposizione molti degli strumenti di cui abbiamo bisogno.

    In Windows 7 è integrato il supporto per i dispositivi multitouch, questo significa che possiamo installare il nuovo SO ed avere la possibilità di accedere in modo standard a
    tutta una nuova generazione di dispositivi senza preoccuparci di interagire troppo a basso livello. Possiamo quindi concentrarci su come utilizzare gli input nella nostra applicazione,
    senza preoccuparci di come intercettare il dato.

    WPF 4.0 inoltre ci permette di astrarre ancora di più le informazioni provenienti dai dispositivi touch per avere un interazione fluida con tutta la UI.

    Nella sessione di Venerì vedremo più in dettaglio tutti questi aspetti, non ultimo, come sviluppare applicazioni multitouch senza dover acquistare dispositivi multitouch e
    come quindi simulare il comportamento dell'utente.

    Vederemo inoltre tutti i nuovi UC che WFP 4.0 ci mette a disposizione e come cambia lo sviluppo delle nostre applicazioni in modo che siano gia pronte per il multitouch.
    In più daremo uno sguardo ad alcuni interessanti progetti che ci permettono di entrare con più consapevolezza in questo nuovo modo di pensare la User Interface.

     

     

     

  • Windows 7 RTM disponibile per il download

    E' finalmente disponibile per gli abbonati MSDN il download della versione Release To Market di Windows 7, e c'è anche il language pack in Italiano.

    Io la scarico....  

  • OT: Ottimizzare i consumi del Samsung I780 durante le connessioni di rete.

     

    Quanto un anno fa ho iniziato ad utilizzare il samsung i780 sono rimasto sorpreso del fatto che nella confezione sono presenti ben 2 batterie e due caricatori con una custodia studiata in modo da permettere la carica della seconda batteria senza che questa fosse inserita nel cellulare.

    Utilizzando normalmente il cellulare che ai tempi aveva montato WM 6.0, ho notato che il telefono senza utilizzare la connessione ad internet arrivava tranquillamente a 4gg di lavoro con una sola batteria.

    Ho aggiornato a WM6.1 e le cose sono rimaste pressocché invariate fino a quando non ho configurato il servizio di sincronizzazione con Exchange.
    Da quel momento in poi ho notato che il cellulare era stranamente caldo e la durata della mia batteria scendeva da 4 giorni a 6-7 ore; ho fatto alcune ricerche ma la durata della mia batteria è andata sempre peggiorando fino a quando ho deciso di disattivare la sincronizzazione con Exchange.

    Ieri mi sono imbattuto in un post interessante, dove consigliavano di attivare il servizio di gestione dinamica del risparmi energetico per le connessioni di rete che di default è “DISATTIVATO”!!.

    Ebbene modificando queste chiavi di registro e riavviando il dispositivo, posso finalmente utilizzare la connessione a Exchange e MSN dal cellulare, mantenendo la durata della mia batteria ad alcuni giorni.
    (Il cellulare non diventa più caldo durante le connessioni ad internet. ) Mi chiedo come mai la configurazione di default sia disattivata!!!:

    [HKEY_LOCAL_MACHINE\Comm\AsyncMac1\Parms]
    "DisablePowerManagement"=dword:1
    Change to
    "DisablePowerManagement"=dword:0
    [HKEY_LOCAL_MACHINE\Comm\Irsir1\Parms]
    "DisablePowerManagement"=dword:1
    Change to
    "DisablePowerManagement"=dword:0
    [HKEY_LOCAL_MACHINE\Comm\PPTP1\Parms]
    "DisablePowerManagement"=dword:1
    Change to
    "DisablePowerManagement"=dword:0
    [HKEY_LOCAL_MACHINE\Comm\L2TP1\Parms]
    "DisablePowerManagement"=dword:1
    Change to
    "DisablePowerManagement"=dword:0

     

    A presto !

  • A C# way to functional programming (parte 2)

     

    Riprendiamo da dove eravamo arrivati, e scriviamo il nostro primo metodo funzionale.
    Implementiamo i metodi IsMatch e ForAll visti nell’esempio del post precedente.

    Per prima cosa abbiamo bisogno di dichiarare una classe statica, infatti i nostri metodi saranno degli extension methods inoltre facciamo in modo tale che il nostro metodo lavori sulle collezioni di oggetti.

     public static class PatternMatchingExtensions
    {
    ...
    }

    Inseriamo a questo punto la dichiarazione dell’extension method IsMatch

    [Description("Search for items that match the pattern. Use Regular Expressions to check the pattern")]
    public static IEnumerable<string> IsMatch(this IEnumerable<string> items, string pattern)
    {
    
    ...
    
    }

    come vediamo, il nostro primo metodo estende una lista di stringhe per effettuare la ricerca e restituisce una lista di stringhe.
    Il codice a questo punto è abbastanza semplice:

     

       [Description("Search for items that match the pattern. Use Regular Expressions to check the pattern")]
        public static IEnumerable<string> IsMatch(this IEnumerable<string> items, string pattern)
        {
          if (string.IsNullOrEmpty(pattern))
            throw new ArgumentNullException("pattern");
    
          Regex rx = new Regex(pattern);
          List<string> result = new List<string>();
          foreach (string item in items)
            if (!string.IsNullOrEmpty(item))
              if (rx.IsMatch(item))
                result.Add(item);
    
          return result;
        } 

    Si tratta di un banalissimo metodo che cicla la lista e restituisce il risultato memorizzato in una nuova lista.
    Ovviamente potevamo scriverlo anche in maniera più coincisa utilizzando la sintassi di linq.

    Spingiamoci ancora un pochino più avanti e creiamo un overload del metodo IsMatch

      [Description("Search for items that match the pattern. Use Regular Expressions to check the pattern")]
        public static IEnumerable<T> Match<T>(this IEnumerable<T> items, Func<T, string> selector, string pattern)
        {
          if (string.IsNullOrEmpty(pattern))
            throw new ArgumentNullException("pattern");
    
          if (selector == null)
            throw new ArgumentNullException("selector");
    
          Regex rx = new Regex(pattern);
          List<T> result = new List<T>();
          foreach (T item in items)
            if (item != null)
              if (rx.IsMatch(selector(item)))
                result.Add(item);
    
          return result;
        }

    Come vediamo in questo overload abbiamo esteso una lista di oggetti generici di cui attualmente non conosciamo il tipo. Abbiamo affidato il compito di ricavare il valore su cui verrà effettuato il match al metodo selector che si appoggia al delegato Func<T, string> per poi valutare tutto come prima attraverso il pattern.
    Chi ha letto il mio post su Generici, Extension Methods e lambda expression sa perfettamente che non ci sarà bisogno di indicare nessun tipo mentre utilizziamo questo extension method perchè il compilatore è in grado di inferire tutti i tipi generici che utilizziamo. Quindi l’utilizzo del nostro nuovo metodo sarà:

    ( facciamo finta di avere una lista di oggetti customers con una proprietà Address)

    List<customers> cust = new List<customers>();
    
    ...
    
    cust.IsMatch(c => c.Address, ".*Annunzio.*");

    stiamo cercando direttamente nella proprietà address attraverso una regex tutte le vie che hanno la parola “Annunzio” al loro interno.
    Bene, scriviamo il metodo ForAll

    Anche in questo caso dobbiamo estendere una lista di oggetti ed anche in questo caso sceglieremo IEnumerable<T> come tipo base.

        [Description("Iterate throw the entire list of elements and call the action method foreach element in the list")]
        public static IEnumerable<T> ForAll<T>(this IEnumerable<T> collection, Do<T> action)
        {
          foreach (T item in collection) action(item);
          return collection;
        }

    Il delegato Do<T> ci permetterà di inserire una lambda expression. La firma del delegato è:

    public delegate void Do<T>(T item);

    Come vedete il metodo ForAll è ancora più semplice del metodo IsMatch, infatti è semplicemente un foreach che richiama la nostra lambda expression.
    In questo caso non manipoliamo direttamente i dati e quindi invece di ritornare void ritorniamo gli stessi dati che abbiamo avuto in ingresso, e quindi IEnumerable<T>.

    Torniamo all’esempio della prima parte:
    Immaginiamo che dobbiamo cercare tutti i customers con indirizzo “Annunzio” e dobbiamo modificare il CAP a 06100 per poi salvare il risultato nel DB.

    List<customers> cust = new List<customers>();
    
    ...
    
    cust.IsMatch(c => c.Address, ".*Annunzio.*")
    .ForAll(c => c.CAP = "06100");

    Con linq avremmo dovuto scrivere qualcosa di più complesso di così.
    Ovviamente il segreto è avere una libreria di metodi già pronti da essere utilizzati in modo funzionale, come abbiamo visto infatti la maggior parte delle funzioni del framework .Net non è pensata per la programmazione funzionale semplicemente.

    Da quello che ho letto e trovato, il team di F# oltre ovviamente a definire la sintassi il compilatore etc. del nuovo linguaggio ha scritto molti metodi che possono essere utilizzati con questo paradigma di programmazione.
    Scrivere una libreria di funzioni in C# come abbiamo visto non è difficile e può essere utilizzata come libreria di base per lo sviluppo di applicazioni generiche permettendoci di sostituire anche i foreach con delle banalissime labda expressions.

    Ritorniamo ancora una volta al nostro esempio e degli indirizzi che contengono la parola “Annunzio” vogliamo quelli che contengono la città Perugia, in quel caso inseriamo un flag per indicare che il cliente è un cliente locale. (l’esempio è assolutamente tirato ad indovinare)

    List<customers> cust = new List<customers>();
    
    ...
    
    cust.IsMatch(c => c.Address, ".*Annunzio.*")
    .ForAll(c => c.CAP = "06100")
    .IsMatch(c => c.Citta, "Perugia")
    .ForAll(c => c.Locale = true);

    Come possiamo vedere la scrittura non si interrompe ed ogni istruzione riparte dal risultato della istruzione precedente.
    Spero di avervi stuzzicato l’appetito, come è successo a me la prima volta che ho visto questo modo di scrivere codice.

    E spero che qualcuno di voi sia così interessato da darmi una mano a scrivere la prima libreria per la programmazione funzionale in C#.
    Ovviamente poi la postiamo su code Plex

  • A C# way to functional programming (parte 1)

     

    C# è un vero linguaggio di programmazione multi-paradigma, possiamo adottare cioè stili (paradigmi) diversi di programmazione senza dover cambiare linguaggio.
    Con l’introduzione nel corso del tempo di alcune caratteristiche al linguaggio, possiamo adottare anche la programmazione funzionale direttamente con il linguaggio C#.

    La programmazione funzionale è uno stile di programmazione in cui il flusso di esecuzione del programma assume la forma di una serie di valutazioni di funzioni. Questo paradigma di programmazione viene solitamente utilizzato nello sviluppo di applicazioni matematiche e in ambiti accademici, ma vedremo che ha i suoi vantaggi anche nella programmazione di applicazioni più classiche, limitando la quantità di codice da scrivere e rendendo più testabili e leggibili i nostri metodi.

    C’è da dire che a breve uscirà in versione RTM un vero e proprio linguaggio dedicato a questo paradigma di programmazione: F#.

    Vediamo che cosa ci serve per iniziare ad utilizzare questo paradigma di programmazione in C#.

    • Microsoft .Net Framework 3.5 (ovviamente con SP1 è meglio ma non è indispensabile)
    • Visual Studio 2008 (non mi ripeto sul discorso del SP)

    A livello di conoscenze tecniche, al fine di capire pienamente il funzionamento di tutto dobbiamo conoscere:

    • Delegati e loro utilizzi attraverso lambda expressions e metodi anonimi.
    • Generics
    • Extension Methods

    A livello di programmatore/utente vedremo che è possibile “ignorare” alcuni dettagli.

    Prima di iniziare a sviluppare è necessario darsi alcune semplici regole che dovremo rispettare durante lo sviluppo dei nostri metodi:

    • Ogni metodo deve essere auto-esaustivo, ovvero non deve fare affidamento a variabili esterne a livello di classe o a livello di ambiente
    • Ogni parametro necessario all’esecuzione dei metodi deve essere passato come argomento dei metodi.
    • Ogni metodo deve avere sempre un valore di ritorno ( non scriveremo mai un metodo “void” per capirci)
    • Ogni metodo verrà scritto sotto forma di extension method.

    Queste regole possono inizialmente sembrare limitative ma vedremo che ci aprono un mondo di possibilità che adesso non riusciamo ad immaginare.
    La cosa migliore è iniziare da un esempio.

    Immaginiamo di avere una lista di stringhe e di voler trovare alcune stringhe attraverso le regular expression.

       1:     List<string> lista = new List<string>();
       2:   
       3:        Regex rx = new Regex(pattern);
       4:        List<string> risultato = new List<string>();
       5:   
       6:        foreach (string ss in lista)
       7:          if (rx.IsMatch(ss))
       8:            risultato.Add(ss);


    Il framework ci mette già a disposizione tutto quello che ci serve, ecco il nostro codice in C# classico: Come vediamo sono appena 5 righe di codice, con il framework 3.5 e l’introduzione di linq possiamo utilizzare un’altra sintassi di programmazione che assomiglia di più alla programmazione funzionale.
    I metodi a supporto di Linq infatti rispondono esattamente ai nostri requisiti e quindi utilizzando una lambda-expression possiamo scrivere

     


       1:  Regex rx = new Regex(pattern);
       2:  var result = (from s in lista
       3:     where rx.IsMatch(s)
       4:     select s).ToList();

    oppure

       1:  Regex rx = new Regex(pattern);
       2:     lista.Where(s => rx.IsMatch(s)); 

     

    Il metodo Where è un metodo (come abbiamo già detto) adatto alla programmazione funzionale
    Il problema però con i metodi di Linq è che possono essere utilizzati in modo molto semplice e produttivo se vogliamo fare delle ricerche, delle selezioni.
    Se dobbiamo scrivere delle operazioni che eseguono delle azioni le cose diventano notevolmente più complicate.

    Se per esempio vogliamo scrivere semplicemente il risultato sulla console dobbiamo necessariamente creare un foreach e al suo interno inserire il comando di scrittura sulla console.

       1:  Regex rx = new Regex(pattern);
       2:     var result = lista.Where(s => rx.IsMatch(s));
       3:     foreach (string s in result)
       4:     Console.WriteLine(s);

     

     

    Voi direte: vabbè, dovè il problema? Nessun problema, solo che potrei semplicemente scrivere:

     


       1:     lista.IsMatch(pattern)
       2:     .ForAll(s => Console.WriteLine(s));

     

    La cosa più interessante di tutte è che dopo il ForAll potrei inserire altre azioni o ricerche che lavorano sul risultato precedente.
    E’ questo il bello della programmazione funzionale.

  • Generics + Extension Methods + Lambda Expression = Wow!!

     

    Studiando F# mi sono chiesto se si potessero applicare alcuni dei suoi principi al mondo C#, per introdurre la programmazione funzionale nelle nostre applicazioni in modo graduale.
    Quindi ho iniziato a scrivere alcuni Extension Methods che mimassero il comportamento di F#.

    Dopo alcuni tentativi ho scoperto una cosa molto interessante su come il motore inferente del compilatore C# risolve i generics.

    Prendiamo per esempio questo metodo:


    public static IEnumerable<TResult> Map<T,TResult>(this IEnumerable<T> items, Func<T,TResult> selector)

    si lo so, non è così immediato, però per capirne il funzionamento dobbiamo vedere necessariamente tutto insieme. 
    Il metodo MAP è uno dei fondamenti della programmazione funzionale in genere ed è ovviamente presente anche in F#.
    Si occupa di eseguire una operazione su una collection di oggetti e ritornare una versione modificata della collection stessa.

    Vediamo un mezzo alla volta:

    1. Metodo: Map<T,TResult>(
      Map utilizza 2 generics, T rappresenta il tipo di ingresso e TResult rappresenta il tipo di uscita.
    2. 1° Argomento: this IEnumerable<T> items
      Il primo argomento stabilisce su quale oggetto posso applicare il mio extension method.
    3. 2° Argomento: Func<T,TResult> selector
      il secondo argomento ci permette di scrivere una lambda expression per manipolare il nostro oggetto T e restituire un nuovo oggetto di tipo differente.
    4. Valore di ritorno: IEnumerable<TResult>
      Il valore di ritorno è una nuova collection di oggetti del tipo TResult.

     

    Prendiamo in esame questo esempio:

    List<string> list = new List<string>();
    list.AddRange(new string[]{“1”,”2”,”3”});

    list.Map<string,int>(s => int.Parse(s));

    In questo esempio utilizziamo l’extension method per convertire un array di stringhe in un array di interi. (Non è importante come è implementato internamente il metodo Map di cui ho fornito solo la firma. Poichè ci interessa come il compilatore inferisce i tipi)
    Ma va scritto proprio così? La risposta è no, ovviamente la scrittura di cui sopra non è errata e nessuno ci vieta di utilizzarla, però esiste una forma + compatta.

    Infatti, non è necessario specificare il tipo T in quanto l’intellisense si accorge che stiamo estendendo un oggetto che eredita da IEnumerable<string> e quindi utilizza il tipo interno dell’IEnumerable e lo assegna al tipo generico T.

    La cosa veramente interessante è che siccome abbiamo inserito una lambda expression all’interno degli argomenti del metodo, il tipo generico TResult viene inferito dal tipo del risultato della lambda expression,
    Quindi nel nostro caso il compilatore sa esattamente che T è un string e TResult è un int.

    Il nostro metodo si trasforma quindi in:

    list.Map(s => int.Parse(s));

    Abbiamo scritto un metodo generico che può essere richiamato senza indicare i tipi dei generics.
    Vi anticipo che si possono inferire in modo automatico + di 2 generics…

    Aspetto vostri commenti !!

    Ciao

  • F# – Un nuovo modo di scrivere software in .Net

     

    Vi invito a visionare questo filmato dove Luca Bolognese, Lead Program Manager per il team del C# e del progetto LINQ a Redmond,
    presenta al PDC 2008 il nuovo linguaggio di programmazione F#.

    http://channel9.msdn.com/pdc2008/TL11/

    A me è piaciuto un sacco e sinceramente sto già facendo qualche esperimento con la beta2.

    Buona Visione.

  • 7° Workshop "Microsoft Office SharePoint Server - Tecnologia e strumenti per lo sviluppo e amministrazione"

    Facciamo un grande in bocca al lupo per i nostri amici di dotnetmarche, che domani in collaborazione con Microsoft e l'università di Camerino, organizzano il 7 workshop su sharepoint. Ancora un grandissimo in bocca al lupo.
    Ecco il link alla pagina dell'evento : http://dotnetmarche.org/eventi/Default.aspx?IDevento=23

  • Windows Azure ... un passo verso il Cloud computing.

    Riporto una notizia che trovo molto importante per lo sviluppo futuro di applicazioni basate sui servizi.
    Microsoft in occasione del PDC ha presentato una nuovissima versione di windows : Windows Azure.

    Il nuovissimo sistema operativo è studiato per supportare a livello di kernel il Cloud Computing.
    Sono già disponibili  SDK ed esempi su come l'infrastruttura funzionerà.

    La cosa mi intriga parecchio perchè il cloud computing è una cosa che mi affascina da parecchio tempo. Avere a disposizione una infrastruttura in grado di supportarlo permette la creazione di applicazioni sicuramente più interessanti.
    Vediamo come evolverà il progetto. Vi riporto il link al sito ufficiale dove è già possibile scaricare dei preview SDK ed esempi.

    http://www.microsoft.com/azure/default.mspx

  • Custom Linq Provider (parte 2)

    Continuiamo a vedere come implementare un provider custom che supporta la sintassi Linq.

    Per prima cosa creiamo un oggetto che implementa le interfacce IQueryable e IQueryProvider. Ecco una prima implementazione :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace CustomLinqProvider
    {
      public class myQueryableObject<T> : IQueryable, IQueryable<T>, IQueryProvider
      {
        private System.Linq.Expressions.Expression _expression = null;

        #region IQueryable Members

        public Type ElementType
        {
          get { return typeof(T); }
        }

        public System.Linq.Expressions.Expression Expression
        {
          get { return _expression; }
          internal set { _expression = value; }
        }

        public IQueryProvider Provider
        {
          get { return this; }
        }

        #endregion

        #region IEnumerable Members

        public System.Collections.IEnumerator GetEnumerator()
        {
          throw new NotImplementedException();
        }

        #endregion

        #region IEnumerable<T> Members

        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
          throw new NotImplementedException();
        }

        #endregion

        #region IQueryProvider Members

        public IQueryable<TElement> CreateQuery<TElement>(System.Linq.Expressions.Expression expression)
        {
          myQueryableObject<TElement> mq = new myQueryableObject<TElement>();
          mq.Expression = expression;
          return mq;
        }

        public IQueryable CreateQuery(System.Linq.Expressions.Expression expression)
        {
          return CreateQuery<T>(expression);
        }

        public TResult Execute<TResult>(System.Linq.Expressions.Expression expression)
        {
          throw new NotImplementedException();
        }

        public object Execute(System.Linq.Expressions.Expression expression)
        {
          throw new NotImplementedException();
        }

        #endregion
      }
    }

     

    I metodi che per adesso ci interessano sono i due metodi CreateQuery. questi metodi vengono chiamati al termine della creazione della Expression Tree da parte del compilatore. La Expression Tree viene preparata e viene passata come oggetto Expression che può essere interpretato ed utilizzato per eseguire le nostre query.

    Come è possibile vedere non viene fatta alcun tipo di elaborazione, semplicemente la expression viene memorizzata all'interno del membro _expression e vine e restituito un oggetto dello stesso tipo che stiamo creando. Questo perchè è molto spesso conveniente implementare IQueryProvider e IQueryable all'interno della stessa classe. Capiremo tra poco il perchè.

    Abbiamo detto che i metodi CreateQuery vengono invocati appena la creazione della expression tree è completata, tuttavia non viene eseguita nessuna elaborazione. Il motivo di questa tardata esecuzione è che ancora non sappiamo come applicare l'Expression Tree; in modo particolare non sappiamo se dobbiamo attenderci un risultato singolo oppure una lista di elementi e il metodo che viene invocato per l'esecuzione della query potrebbe essere differente.

    Facciamo un esempio. Nella query

    var result = from rr in myQueryObject<tabella1>()
                       select rr;

    abbiamo definito che intendiamo ottenere tutti i campi della tabella 1 senza nessun filtro. Tuttavia l'esecuzione potrebbe essere eseguita in uno dei seguenti metodi:

    rr.ToArray();
    rr.Count();
    rr.FirstOrDefault();

    Ognuno di questi metodi applica la query eseguendo operazioni differenti:
    La prima restituisce un risultato multiplo, la seconda esegue un raggruppamento su tutti i record per restituirci il numero di elementi all'interno della tabella, il terzo restituisce il primo elemento completo.

     

    Vediamo quindi come viene invocata l'esecuzione della query.
    La prima grande differenza tra i metodi che invocano la query è il tipo di risultato che andiamo ad ottenere.

    Se il risultato è un elenco di elementi, allora verranno invocati i metodi GetEnumerator() della nostra classe.
    Se invece il risultato è un elemento singolo, allora la query verrà arricchita con l'informazione della chiamata all'ultimo metodo e verrà invocato il metodo Execute().

    Tornando al nostro esempio, nel caso di ToArray() verà invocato il GetEnumerator, nel caso di Count() o di FirstOrDefault(), verrà aggiunto all'Expression Tree l'informazione della chiamata all'ultimo metodo e verrà effettivamente invocato il metodo Execute.

    Quindi per implementare il nostro parser, dovremo implementare sia i metodi Execute che i metodi GetEnumerator di cui abbiamo già gli stub pronti perchè abbiamo implementato le interfaccie.

    E comodo avere implementate entrambe le interfaccie all'interno della stessa classe, poichè il metodo GetEnumerator viene fornito dalla interfaccia IQueryable, mentre il metodo Execute viene fornito dalla interfaccia IQueryProvider.

    E' venuto il momento di capire l'Expression Tree e piegarla alla nostra volontà. L'Expression Tree è la rappresentazione a livello linguaggio delle operazioni che devono essere eseguite per ottenere un certo set di dati.
    Quello che vogliamo fare per prima cosa è capire come "leggere" l'expression tree, per poi interpretarla ed eseguire operazioni Custom.

    Scriviamo questa Query:

    myQueryableObject<int> test = new myQueryableObject<int>();
    var result = from i in test
                 select i;

     

    e vediamo come viene interpretata eseguendo result.Expression.ToString();

     

    value( CustomLinqProvider.myQueryableObject`1[System.Int32] ).Select( i => i )

     

    quello che vediamo è la visualizzazione testuale dell'expression tree. come possiamo vedere ogni operazione viene esplicitata in modo del tutto simile alla chiamata a metodi.
    Quello che accade in realtà, è che ogni sezione della nostra espressione viene rappresentata attraverso un nodo della expression tree.

    Ogni nodo è composto da un oggetto che eredita dalla classe expression. L'oggetto specializza la classe base in modo da rappresentare in modo più fedele possibile il significato del nodo stesso.
    Vediamo quali sono gli oggetti che ereditano da Expression.

    • BinaryExpression
    • ConditionalExpression
    • ConstantExpression
    • InvocationExpression
    • LambdaExpression
    • ListInitExpression
    • MemberExpression
    • MemberInitExpression
    • MethodCallExpression
    • NewArrayExpression
    • NewExpression
    • ParameterExpression
    • TypeBinaryExpression
    • UnaryExpression

     

    Ognuno di questi oggetti rappresenta un particolare tipo di nodo all'interno della nostra espressione. Ogni classe può tuttavia rappresentare più di un tipo di nodo.
    I tipi possibili di nodo sono rappresentati da un Enum.

    public enum ExpressionType
    {
        Add,
        AddChecked,
        And,
        AndAlso,
        ArrayLength,
        ArrayIndex,
        Call,
        Coalesce,
        Conditional,
        Constant,
        Convert,
        ConvertChecked,
        Divide,
        Equal,
        ExclusiveOr,
        GreaterThan,
        GreaterThanOrEqual,
        Invoke,
        Lambda,
        LeftShift,
        LessThan,
        LessThanOrEqual,
        ListInit,
        MemberAccess,
        MemberInit,
        Modulo,
        Multiply,
        MultiplyChecked,
        Negate,
        UnaryPlus,
        NegateChecked,
        New,
        NewArrayInit,
        NewArrayBounds,
        Not,
        NotEqual,
        Or,
        OrElse,
        Parameter,
        Power,
        Quote,
        RightShift,
        Subtract,
        SubtractChecked,
        TypeAs,
        TypeIs
    }
    
    
    

     

    Per interpretare in modo corretto quindi un Expression Tree è sufficiente navigare l'albero e interpretare ogni tipo di nodo. Nel prossimo post vedremo con scrivere in modo corretto un parser per interpretare l'expression tree.
    Vi consiglio di dare un'occhiata ai link che vi riporto.

    Link utili :

    http://msdn.microsoft.com/en-us/library/bb882521.aspx
    http://msdn.microsoft.com/en-us/library/bb882536.aspx
    http://msdn.microsoft.com/en-us/library/bb397951.aspx

  • 070-432 : MS SQL Server 2008, Implementation and Maintenance -> Passed.

    Passato l'esame per l'implementazione e la manutenzione dei DB in SQL Server 2008 .. :D

  • Custom Linq Provider (parte 1)

    Diciamo che il rientro dalle ferie è stato più duro del previsto. In questo tempo però ho avuto modo di approfondire alcuni argomenti piuttosto interessanti legati alla programmazione con il framework 3.5 in modo particolare con Linq.

    Facendo una veloce ricerca su google possiamo accorgerci che le implementazioni custom di linq stanno crescendo in modo piuttosto veloce. Da quelle per fare le query su Amazon a quelle per cercare documenti in Sharepoint a tutto quello che vi può venire in mente. Questo è possibile perchè la sintassi introdotta con il framework 3.5 e che abbiamo visto utilizzare in LinqtoSql o in LinqtoXml non è legata alla implementazione di alcune librerie di accesso ai dati di Microsoft, ma è un nuovo tipo di sintassi introdotta a livello di linguaggio e supportata da 2 interfaccie che sono presenti nelle librerie base del framework 3.5. Quindi è sufficiente reimplementare le interfaccie di base per rendere i nostri oggetti pienamente compatibili con la sintassi Linq.

    L'obiettivo di questo articolo è di comprendere come Linq viene interpretato a livello di compilatore e come viene utilizzato per effettuare ricerche sui dati. Arriveremo anche customizzare il comportamento di Linq per effettuare query su fonti dati non tradizionali. In TeamDev abbiamo seguito questo approccio per estendere le funzionalità del nostro layer di accesso ai dati al fine di sfruttare le interessantissime caratteristiche della sintassi Linq.

    Le interfaccie di base

    Abbiamo detto che linq si appoggia a due interfaccie :

    1. IEnumerable (presente da tempo nella libreria mscorlib)
    2. IQueryable (introdotta con il framework 3.5 nella libreria System.Core)

    queste interfaccie vengono riconosciute dal compilatore e rendono possibile l'utilizzo della sintassi Linq. Comprendere come il compilatore utilizza le interfaccie, aiuta a comprendere come Linq funziona e come possiamo customizzarne il comportamento.

    public interface IEnumerable
    {
        IEnumerator GetEnumerator();
    }
    
     

    IEnumerable è presente dalla prima implementazione del framework a supporto della sintassi foreach. Possiamo infatti utilizzare il foreach solo sugli oggetti che implementano IEnumerable.
    Siccome Linq utilizza IEnumerable per effettuare le query che coinvolgono collection e liste, questo ci lascia intuire che tutti i foreach possono essere trasformati in query Linq.

    public interface IQueryable : IEnumerable
    {
        Type ElementType { get; }
        Expression Expression { get; }
        IQueryProvider Provider { get; }
    }
     

    IQueryable è stata introdotta con la versione 3.5 del framework e si trova in System.Core. L'implementazione di IQueryable permette di customizzare il comportamento della query linq per adattarla ad una sorgente dati particolare.
    Mentre le query  su oggetti IEnumerable vengono eseguite in memoria , le query su IQueryable possono essere trasformate in query custom su oggetti di ogni tipo.

    Tutto questo è possibile grazie alla classe Expression e alla interfaccia IQueryProvider esposte attraverso IQueryable

    Come vengono utilizzate le interfaccie

    Quando utilizzata con IQueryable, la query linq viene trasformata dal compilatore in un oggetto di tipo Expression (detto anche ExpressionTree , perchè ha una struttra ad albero).
    L'oggetto Expression viene passato ad un provider che provvede ad interpretarlo e restituirà un risultato coerente con la query effettuata.

    Quando utilizzata con IEnumerable, la query linq viene immediatamente eseguita attraverso degli extension methods che estendono le funzionalità della interfaccia IEnumerable.

    E facile intuire quindi che per customizzare il comportamento delle query Linq dobbiamo implementare una delle suddette interfaccie.
    Agendo con Reflector ci accorgiamo anche che il modo più corretto per intervenire è utilizzare IQueryable piuttosto che IEnumerable, questo perchè IEnumerable ha lo scopo di effettuare operazioni in memoria, cosa che probabilmente vorremo continuare a fare.

    IQueryable invece è pensata per agire fuori dal contesto dell'applicazione e quindi è l'interfaccia che meglio si presta alla realizzazione di provider custom per l'accesso ai dati.

    Nel prossimo post vedremo come è strutturata la classe Expression e come creare un parser per tradurre le Expression Tree in tutto ciò che vogliamo.

  • Book Review: Beginning Web Development, Silverlight, and ASP.NET Ajax

    Il libro “Beginning Web Development, Silverlight, and ASP.NET Ajax”, scritto da Laurance Moroney, è una introduzione alla programmazione Web, adatto in modo particolare per chi inizia ad affacciarsi a questo mondo. E’ diviso in 3 parti principali di cui la prima, dopo un capitolo di storia sul mondo web, introduce ai principi dello sviluppo ASP.Net 2.0. Guida passo-passo il principiante a creare la prima applicazione Web, spiegando anche il funzionamento di base di Visual Studio e affrontando progressivamente gli argomenti fondamentali come WebForms, DataBing, WebServices.

    Book Review:  Beginning Web Development, Silverlight, and ASP.NET Ajax

     

     

     

     

     

     

     

     

     

     

     

     

     

    Nella seconda parte viene fatta una carrellata delle nuove tecnologie introdotte con la versione 3.0 di Microsoft .Net Framework: Windows Communication Foundation, Windows Presentation Foundation, Windows Workflow Foundation.
    Nell’ultima parte viene ripreso l’argomento Web, dove viene illustrata l’evoluzione che ha portato ad Ajax per affrontare infine Silverlight.

    Il libro è decisamente introduttivo e getta le basi per ulteriori approfondimenti. Di facile lettura è pienamente comprensibile anche da un programmatore inesperto. Non approfondisce troppo nessun argomento lasciando al lettore la giusta dose di curiosità per ulteriori letture. Una cosa molto importante da sottolineare è la visione di insieme che si ottiene dalla lettura di questo libro dove tutte le tecnologie affrontate trovano il loro giusto posto.

  • [OT] TS: MS .NET Framework 3.5, ADO .NET Application Development --> Passed

     Anche io mi sto dilettando con gli esami in Beta. E proprio questa sera ho saputo di aver passato il 70-561 : TS: MS .NET Framework 3.5, ADO .NET Application Development

    Geeked

  • Uno snippet per le DependencyProperty su WPF

    Mi capita molto spesso di creare DependencyProperty per i miei oggetti da utilizzare con WPF.
    Nello snippet base devo sostituire continuamente UIPropertyMetadata con FrameworkElementMetadata, quindi ho deciso di farmi uno snippet gia modificato.

    Ve lo allego.
    Potete richiamarlo con propdpf

    Per installarlo è sufficiente copiare il file nella cartella
    C:\Program Files\Microsoft Visual Studio 9.0\VC#\Snippets\1033\NetFX30\

More Posts Next page »
dotNet Umbria 2007-2008
Powered by Community Server (Commercial Edition), by Telligent Systems