Visualizzazione post con etichetta .NET Framework. Mostra tutti i post
Visualizzazione post con etichetta .NET Framework. Mostra tutti i post

07 aprile 2009

Nuovo blog tecnico

Vi segnalo che ho aperto un nuovo blog completamente dedicato al mondo dell’informatica, mia passione seconda solo alla fotografia.

Il link del blog è http://codetailor.blogspot.com.

28 marzo 2009

VB.NET : Copiare automaticamente le proprietà di un oggetto in un altro grazie alla Reflection

L’extension method che voglio postare questa volta consente di copiare le proprietà (almeno in lettura) di un oggetto sorgente, nelle proprietà (dello stesso tipo, con lo stesso nome e, almeno, in scrittura) di un altro oggetto:

<Extension()> _
Public Sub CopyFrom(ByVal destObj As Object, _
                   
ByVal sourceObj As Object)
    Dim sourceType = sourceObj.GetType()
    Dim destType = destObj.GetType()
    Dim sourceProperties = (From p In sourceType.GetProperties() _
                            Where p.CanRead _
                            Select p).ToList()
    For Each sourceProp In sourceProperties
        Dim propName = sourceProp.Name
        Dim destProp = destType.GetProperty(propName)
        If destProp IsNot Nothing AndAlso destProp.CanWrite Then
            If sourceProp.GetType().Equals(destProp.GetType()) Then
                Dim propValue = sourceProp.GetValue(sourceObj, Nothing)
                Try
                    destProp.SetValue(destObj, propValue, Nothing)
                Catch ex As Exception
               
End Try
            End If
        End If
    Next
End Sub

Utilizzando questo moetodo possiamo scrivere:

.
.
Dim destObj as Object
destObj.CopyFrom(sourceObj)
.
.

in modo da copiare tutte le proprietà di sourceObj nelle proprietà comuni di destObj.

25 febbraio 2009

Articolo su ioProgrammo n°136 di Marzo

E’ uscito un mio articolo sul numero di Marzo della rivista ioProgrammo dal titolo “Utilizzare gli RSS come fonte dati”.

 

24 febbraio 2009

03 febbraio 2009

VB.NET : My.Computer.Network.IsAvailable vs schede di rete virtuali

Se state utilizzando l’oggetto Network di My.Computer ed in particolare la proprieta’ IsAvailable fate attenzione perche’ viene ingannata dalla presenza di schede di rete virtuali.

Nella mia macchina di sviluppo, infatti, ho due schede virtuali installate da VMWare e, anche se mi disconnetto dalla rete, IsAvailable continua ad essere sempre a true.

Se disabilito le schede virtuali, ovviamente, IsAvailable ritorna a lavorare correttamente.

Per risolvere questo problema potete utilizzare IsAvailable in combinazione con Ping andando a vedere se, effettivamente si “pinga” un indirizzo di rete noto:

If My.Computer.Network.IsAvailable = True And
   My.Computer.Network.Ping([indirizzo], 10000) Then
     ' Computer connesso
Else
     ' Computer disconnesso
End If

dove [indirizzo] e’ un indirizzo noto.

Altra soluzione e’ quella di richiamare, tramite P/Invoke, la dll di sistema wininet.dll ed in particolare la funzione di libreria InternetGetConnectedState.

Definiamo la dllimport:

DllImport("wininet.dll")> _
Public Function InternetGetConnectedState(ByRef flags
    As UInt32, ByVal dwReserved As UInt32) As Boolean
End Function

e il controllo sulla presenza di rete diventa:

If InternetGetConnectedState(0, 0) = True Then
     ' Computer connesso
Else
     ' Computer disconnesso
End If

Ho testato il tutto su diversi sistemi operativi e mi manca solo Windows Server 2008, ma per il resto sembra funzionare.

28 gennaio 2009

Pubblicato un articolo su ioProgrammo di febbraio

Sul numero 135 di ioProgrammo è presente un mio articolo sul linguaggio Buddy Script.

15 gennaio 2009

System.Diagnostics.Stopwatch: misurare correttamente gli intervalli di tempo

La classe StopWatch è molto interessante.

Non la ricordavo e me l’ha fatta tornare in mente il buon Davide Vernole nel suo blog:

Questo post più per mia memoria che per utilità comune. Qualche anno fa ho scoperto questa classe del framework per eseguire una corretta lettura di intervalli di tempo multipli durante l’esecuzione di codice .NET (leggi C# nel mio caso). Purtroppo la mia memoria è limitata e ogni volta che devo usarla perdo un pò di tempo a ricordarmi come si chiama e/o in che namespace la trovo. Quindi ho deciso di scriverlo nel blog per, spero, ritrovarla prima in futuro. Mi ricorderò poi che l’ho messa nel blog? Chissà…Per chi volesse saperne di più su questa classe ecco il link ad MSDN: Classe Stopwatch

System.Diagnostics.Stopwatch: misurare correttamente gli intervalli di tempo

10 gennaio 2009

Articolo : Un reminder per Team Foundation Server 2005

In questo post vorrei pubblicare un mio vecchio articolo (di un annetto fa) che mostra come interrogare l’object model di team Foundation Server (in questo caso nella versione 2005) per ottenere le attività da svolgere in riferimento ad un utente.

Quest’articolo prende spunto dalla realizzazione di un semplice software che avverte l’utente della presenza di nuovi elementi di lavoro assegnatigli in Team Foundation Server, per esaminare le potenzialità del tool di gestione dei progetti di Microsoft a proposito della sua estensibilità ed espandibilità. In particolare prenderemo in esame il sottoinsieme di API riguardanti la gestione dei work items.

L’object model di Team Foundation Server

Prima di cominciare a progettare il nostro software, occupiamoci di dare un’occhiata all’object model di Team Foundation Server, cioè all’insieme di classi messe a disposizione degli sviluppatori per interagire con il server di Team Foundation.

Innanzitutto osserviamo che Team Foundation utilizza SQL Server 2005 quale base dati per memorizzare tutto ciò che riguarda i progetti da lui gestiti e questo comporta che, almeno in linea di principio, potremmo pensare di accedere ai dati (progetti, versioni dei file, elementi di lavoro e quant’altro) leggendo le tabelle del data base.

Questa tecnica, pur se praticabile, è sconsigliata poiché si può essere certi che la struttura del database (tabelle, viste, stored procedure, etc., etc.) rimanga inalterata nel tempo.

Per tale motivo, il modo migliore per accedere ai dati di Team Foundation Server è di utilizzare proprio l’object model messo a disposizione.

La classe fondamentale per accedere ai servizi esposti da Team Foundation è la classe TeamFoundationServer del namespace Microsoft.TeamFoundation.Client.

Questa classe, mostrata in figura 1, ci consente di eseguire la connessione al server e di richiedere uno dei tanti servizi messi a disposizione.

Figura1

Possiamo osservare che la classe implementa l’interfaccia IServiceProvider ovvero l’interfaccia che consente di definire un meccanismo per il recupero di un oggetto Service, vale a dire un oggetto che offre un supporto personalizzato ad altri oggetti.

E’ grazie a questa interfaccia che possiamo utilizzare del metodo GetService() che ci permette di recuperare uno dei servizi messi a disposizione Team Foundation Server.

Vedremo in seguito come utilizzare il metodo GetService(), per ora limitiamoci a segnalarne l’esistenza e spostiamo l’attenzione su come instaurare una connessione al server di Team Foundation tramite la classe TeamFoundationServer.

Abbiamo due modalità:

  • utilizzando il costruttore della classe (che in alcuni dei suoi overload accetta oggetti ICredentials o ICrdedentialsProvider contenenti le credenziali di connessione);
  • utilizzando la classe TeamFoundationServerFactory che permette di ottenere un’istanza della classe TeamFoundationServer tramite il metodo GetServer().

Esaminiamo in dettaglio la seconda strada, cioè l’utilizzo della TeamFoundationServerFactory, poiché rappresenta la modalità ottimizzata per ottenere un riferimento al server di Team Foundation.

La classe TeamFoundationServerFactory, infatti, gestisce una propria cache interna relativa alle connessioni e alle informazioni sulle stesse. Ogni qual volta che ne è richiesta una con il metodo GetServer(), viene eseguito un controllo se la connessione richiesta è presente o meno tra quelle della cache e, eventualmente, restituita senza effettuarla di nuovo.

Il metodo GetServer() ha due differenti overload uno dei quali prevede, come argomento, il nome del server di Team Foundation, mentre l’altro prevede oltre, a questo, anche un oggetto di tipo ICredentialsProvider che rappresenta l’oggetto da invocare nel caso l’autenticazione di rete del client che esegue la richiesta fallisca.

Vedremo, nella parte riguardante il codice, come gestire l’autenticazione in maniera trasparente per l’utente oppure lasciare allo stesso la responsabilità di digitare username e password.

Nel momento in cui si ha un oggetto di classe TeamFoundationServer (sia con i costruttori della stessa o attraverso l’utilizzo della Factory), è necessario invocare il metodo Authenticate() per avviare la richiesta di autenticazione sul server.

Il metodo utilizza l’oggetto ICredentialsProvider (passato come parametro del costruttore o nel metodo GetServer() factory) per gestire l’autenticazione.

Non appena si è stabilita la connessione al server, è possibile richiedere uno dei servizi disponibili.

In quest’articolo prendiamo in esame solamente i servizi riguardanti la gestione degli elementi di lavoro (workitems).

La classe che ci permette di gestire gli elementi di lavoro è la WorkItemStore (figura 2) che si ottiene dal server con la chiamata:

server.GetService(GetType(WorkItemStore))

Figura2

La classe WorkItemStore si trova nel namespace Microsoft.TeamFoundation.WorkItemTracking.Client e fornisce una serie di metodi che permettono di recuperare, creare o modificare elementi di lavoro presenti in un qualunque progetto all’interno del server di Team Foundation.

La WorkItemStore espone la proprietà Projects (di tipo ProjectCollection) contenente la lista dei progetti presenti all’interno del server (ogni elemento della ProjectCollection è un oggetto Project) e la proprietà FieldDefinitions (di tipo FieldDefinitionCollection) contenente la lista delle definizioni dei campi disponibili nel server per un elemento di lavoro.

Per recuperare l’elenco degli elementi di lavoro all’interno del server e relativi a tutti i progetti o a un particolare progetto, si utilizza il metodo Query() che prevede la possibilità di eseguire una query di tipo custom (con il linguaggio WIQL, in modo analogo a quello che si fa con un database), oppure una delle query presenti nella lista delle query disponibili sul server.

Per recuperare le query predefinite, è possibile utilizzare il metodo GetStoredQuery() che permette di ottenere un oggetto StoredQuery da cui è possibile ricavare la query in linguaggio WIQL che può essere utilizzata all’interno del metodo Query().

Il metodo Query() ritorna un oggetto WorkItemCollection contenente i singoli WorkItem risultanti dalla richiesta (figura 3).

Figura3

La classe WorkItem (presente nel namespace Microsoft.TeamFoundation.WorkItemTracking.Client) incapsula l’elemento di lavoro di Team Foundation Server ed espone tutte le proprietà dello stesso, dal titolo fino ad arrivare allo stato o all’assegnatario dello stesso.

E’ possibile eseguire una query anche limitatamente da uno dei progetti contenuti nella collezione dei progetti di WorkItemStore, in questo caso la query concernerà i soli elementi di lavoro del progetto e non dell’intero server.

Progettiamo il nostro reminder

L’applicativo che realizzeremo ha la caratteristica di avviarsi mostrando un’icona all’interno della tray bar e di avvertire l’utente, tramite un pop-up, nel momento in cui ci si accorge della presenza di nuovi elementi di lavoro.

Il cuore dell’applicativo è una classe, che chiamiamo WorkItemsManager le cui responsabilità sono quelle di connettersi al server di Team Foundation, eseguire un polling all’indirizzo dello stesso, per capire se sono presenti nuovi elementi di lavoro, e gestire tutti i meccanismi di disconnessione e riconnessione verso il server stesso.

I riferimenti a Team Foundation Server, quali nome del server, account di connessione (in termini di username e password) ed eventuale dominio sono memorizzati all’interno del file di configurazione app.config e sono esposti dalla classe WorkItemsManager tramite apposite proprietà.

La figura 4 mostra l’insieme delle classi necessarie per implementare le funzionalità che abbiamo in mente.

Figura4

Connessione ad un server di Team Foundation

Per poter gestire la connessione al server di Team Foundation impostando i dati di connessione da codice e non chiedendoli ogni volta all’utente, abbiamo la necessità di realizzare un CredentialsProvider.

Come già visto in precedenza, un CredentialsProvider (che deve implementare l’interfaccia ICredentialsProvider) è utilizzato dalla TeamFoundationServer nel momento in cui la classe stessa tenta la connessione al server per richiedere le credenziali di accesso da utilizzare.

In questo caso viene richiamato il metodo GetCredentials() che, per inciso, è uno dei due metodi dell’interfaccia ICredentialsProvider, e che ha la responsabilità di restituire un oggetto ICredentials per la connessione.

Nel nostro caso specifico, la classe che si occupa di ciò è la TFSNetworkCredential che, nel metodo GetCredentials(), crea un oggetto NetworkCredential con lo username, la password ed il dominio specificato.

La classe WorkItemsManager, dispone di un metodo Connect() che permette, una volta impostati username, password, domani e nome del server di Team Foundation, di connettersi fisicamente al server.

A livello di codice viene utilizzata una TeamFoundationServerFactory ed un oggetto TFSNetworkCredential, come mostrato di seguito:

Dim icp As ICredentialsProvider = New TFSNetworkCredential(Me.Username, Me.Password, Me.Domain)
Try
    Me._TeamFoundationServer = TeamFoundationServerFactory.GetServer(Me.ServerName, icp)
    Me._TeamFoundationServer.Authenticate()
    RaiseEvent Connected()
Catch ex As Exception
    Me._TeamFoundationServer = Nothing
    RaiseEvent NotConnected()
End Try

Il flusso di esecuzione prevede la creazione di un oggetto di gestione delle credenziali (TFSNetworkCredential nel nostro caso), il recupero di un oggetto TeamFoundationServer tramite la TeamFoundationServerFactory ed il metodo GetServer() (nel nostro caso l’attributo private _TeamFoundationServer), infine la chiamata al metodo Authenticate() per effettuare l’autenticazione vera e propria.

La classe WorkItemsManager dispone di due eventi per segnalare ai client che la utilizzano, l’avvenuta connessione o disconnessione.

Gestire i WorkItems

Stabilita la connessione al server, è necessario implementare un meccanismo di polling che, periodicamente, effettua una query all’indirizzo di Team Foundation Server per recuperare i nuovi ed eventuali elementi di lavoro.

Per implementare questo meccanismo ci viene in aiuto il multithreading.

La classe WorkItemsManager prevede, infatti, un attributo privato di tipo Thread, due metodi per avviare e fermare il thread ed un blocco di codice che effettua il polling.

Concentriamoci sulla parte di codice che implementa l’accesso ai work items.

Se esiste la connessione a Team Foundation Server, viene richiesto il servizio WorkItemStore utilizzando il metodo GetService() della classe TeamFoundationServer, quindi viene eseguita una particolare query con il metodo Query() della classe WorkItemStore e memorizzata la collezione degli elementi di lavoro ritornata con lo stesso.

Dim ItemStore As WorkItemStore = CType(Me._TeamFoundationServer.GetService(GetType(WorkItemStore)), WorkItemStore)

Dim query As String = "SELECT [System.Id], [Microsoft.VSTS.Common.Rank], [System.WorkItemType], [System.State], [System.Title],[System.ChangedDate] FROM WorkItems WHERE [System.AssignedTo] = @me AND [System.State] <> 'Closed' ORDER BY [System.ChangedDate] desc"

_WorkItems = ItemStore.Query(query)

La select presente nella stringa query è la query in formato WIQL che recupera tutti gli elementi di lavoro assegnati all’utente corrente ([System.AssignedTo] = @me) e non ancora chiusi ([System.State]<>’Closed’).

Recuperato l’elenco degli elementi di lavoro dell’utente e memorizzati nell’attributo _WorkItems (esposto con la proprietà WorkItems), si procede al controllo degli elementi inseriti successivamente all’ultima data di polling. Nel nostro caso eseguiamo una scansione della collezione degli elementi di lavoro controllando la data di modifica (ChangedDate):

Dim iNewWorkItems As Integer = 0
For Each wi As WorkItem In _WorkItems
    If wi.ChangedDate > Me.LastCheckDate Then
        If WorkItem.ChangedDate > lastdate Then
            lastdate = wi.ChangedDate
        End If
        iNewWorkItems += 1
    End If
Next

Avremmo potuto ottenere lo stesso risultato eseguendo la query filtrata per data di cambiamento successiva all’ultima data di controllo memorizzata nella proprietà LastCheckDate.

Se sono trovati dei nuovi elementi di lavoro, viene sollevato un evento NewWorkItems:

If iNewWorkItems > 0 Then
    RaiseEvent NewWorkItems(iNewWorkItems)
End If

Eseguito il controllo per verificare la presenza di nuovi elementi di lavoro, si attende per un periodo di tempo pari al numero di secondi impostato nella proprietà PollingTime prima di ripetere l’operazione di query verso il server.

Da notare che l’attesa non viene implementata tramite una semplice chiamata al metodo Thread.Sleep() ma con un pezzo di codice leggermente più complesso:

For i As Integer = 0 To Me._PollingTime - 1
    System.Threading.Thread.Sleep(1000)
    If Not Me._bThreadAlive Then
        Exit For
    End If
Next

In questo caso effettuiamo un’attesa di un secondo da ripetere per tante volte quante sono le unità impostate nella proprietà PollingTime.

Questo meccanismo ci consente di poter controllare, durante l’attesa, se il thread deve essere chiuso (magari perché il client è stato chiuso dall’utente) e di terminarlo, quindi, in maniera corretta.

Ciò non sarebbe accaduto se avessimo utilizzato lo Sleep(), caso in cui avremmo dovuto attendere il termine della pausa.

Ultima osservazione da proporre prima di passare al client vero e proprio che utilizza la nostra classe, riguarda l’implementazione dell’interfaccia IDisposable da parte di WorkItemsManager.

Nel momento in cui la classe non viene più utilizzata, si deve garantire una corretta chiusura del thread di lavoro ed è per questo motivo che si è scelto di implementare l’interfaccia IDisposable e di demandare al metodo Dispose() la chiusura effettiva del thread di lavoro.

Il client vero e proprio

Analizziamo, ora, il client (molto semplice a dire la verità) che fa uso della classe WorkItemsManager creata nel paragrafo precedente.

L’applicazione client è composta da un eseguibile che si avvia mostrando un’icona nella tray bar (l’icona sarà differente in base allo stato di connessione al server e alla presenza o meno di nuovi items di lavoro), che segnala con un pop up l’arrivo di nuovi elementi di lavoro e che visualizza, a richiesta dell’utente, l’elenco completo dei work items.

Il client è formato da una form principale con un attributo privato di tipo WorkItemsManager.

Nel gestore dell’evento load della form si recuperano le informazioni relative alla connessione verso il server di Team Foundation (presenti nel file di configurazione dell’applicazione stessa):

Dim servername As String = ConfigurationManager.AppSettings("ServerName")
Dim username As String = ConfigurationManager.AppSettings("UserName")
Dim password As String = ConfigurationManager.AppSettings("Password")
Dim domain As String = ConfigurationManager.AppSettings("Domain")

si istanzia la classe WorkItemsManager:

Me._WorkItemManager = New TFSLibrary.WorkItemsManager(servername, username, password, domain)

si “agganciano” gli opportuni gestori di evento sulla classe WorkItemsManager:

AddHandler _WorkItemManager.Connected, AddressOf WorkItemManager_Connected
AddHandler _WorkItemManager.NotConnected, AddressOf WorkItemManager_NotConnected
AddHandler _WorkItemManager.NewWorkItems, AddressOf NewWorkItems

e, finalmente, si avvia il meccanismo di controllo dei nuovi elementi di lavoro:

_WorkItemManager.Start()

I gestori di evento ci permettono di implementare la funzionalità di cambiamento della icona nella tray bar e il pop-up di arrivo nuovi elementi di lavoro, in particolare nei gestori degli eventi Connected() e NotConnected() modifichiamo in maniera opportuna l’icona per segnalare la connessione o la disconnessione al server.

In maniera analoga il gestore di evento NewWorkItems si occupa di visualizzare il pop-up indicante il numero di nuovi elementi di lavoro presenti e modificare l’icona della tray bar per segnalare la presenza degli stessi.

Da segnalare l’utilizzo della classe IconManager che consente di recuperare le icone compilate all’interno dell’assembly principale dell’applicazione grazie all’utilizzo della tecnica Reflection e della funzione:

Private Shared Function GetResourceIcon(ByVal iconName As String) As Icon
    Dim icon As System.Drawing.Icon = Nothing
    Dim asm As System.Reflection.Assembly = Nothing
    Dim st As System.IO.Stream = Nothing
    asm = Reflection.Assembly.GetExecutingAssembly
    Try
        st = asm.GetManifestResourceStream("WorkItemReminder." + iconName)
        icon = New System.Drawing.Icon(st)
    Catch ex As Exception
        icon = Nothing
    Finally
        If Not st Is Nothing Then
            st.Close()
        End If
    End Try
    Return icon
End Function

Le icone utilizzate dell’applicativo, infatti, sono state compilate come risorse embedded dell’assembly e possono essere recuperate dall’assembly stesso tramite la funzione GetManifestResourceStream() applicata all’assembly principale dell’applicazione.

Questa tecnica può essere utilizzata per qualsiasi tipo di file o risorsa che l’applicazione deve utilizzare ma che non si vuole distribuire come file esterno alla stessa (magari perché non si vuole che sia modificato).

Conclusioni

L’articolo non ha la pretesa di esaurire tutte le funzionalità della gestione degli elementi di lavoro in Team Foundation Server ma si prefigge lo scopo di dare spunti che possono essere colti per esplorare l’object model di Team Foundation (abbastanza vasto e complesso). In questo modo sarà possibile, se la situazione lo richiederà, personalizzare, tramite opportune applicazioni, un ambiente di lavoro già molto completo ed esaustivo ma che resta comunque estensibile e configurabile a piacimento e con discreta facilità.

La classe WorkItemManager può rappresentare un punto di partenza per realizzare una propria classe che gestisce, oltre che la presenza di nuovi elementi di lavoro, anche le funzionalità di modifica e inserimento degli stessi con un’interfaccia grafica che non sia necessariamente quella fornita da Visual Studio.

Scaricate l’articolo in formato pdf e il codice sorgente dal seguente link:



09 gennaio 2009

Due articoli su ioProgrammo di Gennaio

Scrvo questo post solo per segnalare l’uscita di due miei articoli ioProgrammo-134 nel numero 134 di ioProgrammo in edicola a Gennaio:

  • Progettare un bot per Live Messenger
  • RSS una lingua franca anche per i database

 

 

 

29 ottobre 2008

.NET : Controlli gratuiti da DevExpress

Girando tra i vari blog, mi sono imbattuto nella possibilità di scaricare dei controlli gratuiti della DevExpress per sviluppatori .NET Framework.

Se siete interessati fatevi un giro su questo sito.

28 settembre 2008

VB.NET : Un extension method per ridimensionare una bitmap

Questo semplice extension method consente, a partire da un oggetto bitmap, di ottenere un nuova bitmap uguale a quella di partenza ma ridimensionata in base ad un fattore di larghezza e a uno di altezza:


<Extension()> _
Public Function CloneResize(ByVal image As Bitmap, ByVal zoomFactorWidth As Double, ByVal zoomFactorHeight As Double) As Bitmap
Dim width = image.Width
Dim height = image.Height
Dim newImage = New Bitmap(image, width * zoomFactorWidth, height * zoomFactorHeight)
Return newImage
End Function




Grazie a questo metodo possiamo, ad esempio ottenere, a partire dall’icona di sistema che indica il warning, una bitmap di dimensioni raddoppiate:



Drawing.SystemIcons.Warning.ToBitmap().CloneResize(2, 2)


image



20 settembre 2008

Articoli : Windows Live Messenger su ioProgrammo

Save a tutti,

è uscito, sul numero di ottobre di ioProgrammo, il mio articolo riguardante  Windows live Messenger.

 ioProgrammo numero 131

Si tratta del mio primo articolo su questa testata......speriamo bene!!!

 

30 aprile 2008

VB.NET: Convertire un oggetto IQueryable in una DataTable

L'extension method che vi propongo oggi converte un oggetto che implementa l'interfaccia IQueryable in una DataTable.

L'argomento fieldNames è una stringa nella forma:

proprieta1[?];proprieta2[?];.....;properietaN[?]

dove:


proprieta : è il nome di una proprietà dell'oggetto contenuto nell'argomento "IQueryable" che diventerà una colonna della DataTable risultato;

? : è facoltativo ed indica che la colonna può contenere valori nullable.


La proprietà può essere anche una sottoproprietà dell'oggetto.


L'extension method fa uso della funzione statica esposta nel post VB.NET : Recuperare il valore o il tipo di una proprietà in maniera ricorsiva tramite reflection.


<Extension()> _
Public Function ToDataTable(ByVal queryableObj As IQueryable, _
ByVal fieldNames As String) As DataTable
Dim retTable As New DataTable
' recupero il tipo di oggetto di cui è formata l'interfaccia
Dim objType = queryableObj.ElementType
Dim fields = fieldNames.Split(";")
' creo le colonne
For Each field In fields
If Not String.IsNullOrEmpty(field) Then
Try
Dim
propName = field.Replace("?", "")
Dim colType = ReflectionUtility.GetPropertyType(objType, propName)
Dim colName = propName.Replace(".", "_")
Dim col As New DataColumn With {.ColumnName = colName, _
.DataType = colType, _
.AllowDBNull = field.EndsWith("?")}
retTable.Columns.Add(col)
Catch ex As Exception
End Try
End If
Next
' riempio le colonne
For Each currObj In queryableObj
Dim row = retTable.NewRow
For Each field In fields
Dim propName = field.Replace("?", "")
Dim colName = propName.Replace(".", "_")
If retTable.Columns.Contains(colName) Then
row(colName) = ToBDNullableValue(ReflectionUtility.GetPropertyValue(currObj, field))
End If
Next
retTable.Rows.Add(row)
Next
Return
retTable
End Function

Public Function
ToBDNullableValue(ByVal obj As Object) As Object
Dim
retObj As Object = DBNull.Value
If obj IsNot Nothing Then
retObj = obj
End If
Return
retObj
End Function

Per chiarire la situazione facciamo un'esempio, supponiamo di avere il seguente pezzo di codice:



Dim dipendenti As Dipendente() = _
{New Dipendente With {.Cognome = "Bianchi", _
.Nome = "Carlo", _
.DataNascita = New DateTime(1970, 2, 26)}, _
New Dipendente With {.Cognome = "Verdi", _
.Nome = "Giuseppe", _
.DataNascita = New DateTime(1978, 1, 1)}, _
New Dipendente With {.Cognome = "Rossi", _
.Nome = "Bruno", _
.DataNascita = New DateTime(1980, 1, 1)}, _
New Dipendente With {.Cognome = "Bonaventura", _
.Nome = "Alessandro", _
.DataNascita = New DateTime(1960, 1, 1)}}

Dim persTable = dipendenti.AsQueryable().ToDataTable("Cognome;Nome;DataNascita.Year")


La tabella persTable conterrà:


image


L'esempio mostra come l'extension method possa essere utilizzato anche con normali array grazie all'extension method AsQueryable() presente nel framework .NET 3.5.



I nomi delle colonne della DataTable sono uguali ai nomi delle proprietà passate per argomento con il '.' sostituito con '_'.



 



29 aprile 2008

VB.NET: Snippet per creare automaticamente le proprietà in Visual Studio

Una delle nuove caratteristiche di C# 3.5 è la possibilità di definire le proprietà senza dover scrivere il codice di set e get e definire l'attributo privato che, dietro le quinte, contiene il valore.

Putroppo VB non prevede questa sintassi e, così ho realizzato un semplice snippet per automatizzare l'iter noioso della creazione delle proprietà.

Lo snippet crea il seguente codice:

Private_AttributeName As AttributeType
Public PropertyAttributeName() AsAttributeType
    Get
        Return Me
._AttributeName
    End Get
    Set
(ByValvalue AsAttributeType)
        Me._AttributeName = value
    End Set
End Property

 

dove AttributeName è il segnaposto per il nome dell'attributo e AttributeType il segnaposto per il tipo dell'attributo (e, quindi, della proprietà).

Lo snippet è scaricabile dal mio spazio su SkyDrive.

 

28 aprile 2008

VB.NET : Recuperare il valore o il tipo di una proprietà in maniera ricorsiva tramite reflection.


Le due funzioni che vi propongo consentono di recuperare, in maniera ricorsiva, il valore o il tipo di una proprietà (pubblica) di un oggetto.

La proprietà può essere anche una delle proprietà di un oggetto aggregato all'oggetto di partenza, ad esempio:

dim fInfo as new FileInfo("c:\prova.txt")
dim value as object = getPropertyValue(fInfo,"Directory.LastAccessTime.Day")

recupera la proprietà Day (Integer) della proprietà LastAccessTime (di tipo DateTime) contenuta nella proprietà Directory (di tipo DirectoryInfo) dell'oggetto fInfo.


E' possibile indicare l'indice dell'oggetto da recuperare nel caso delle proprietà indicizzate (array, collection, etc., etc.).


In maniera analoga lavora la funzione che recupera il tipo della proprietà.

Imports System.Reflection
Public
Shared Function GetPropertyType(ByVal objType As Type, _
ByVal propertyName As String) As Type
Dim retval As Object = Nothing
Dim strArray = propertyName.Split(".")
If strArray.Count > 0 Then
Dim propinfo As PropertyInfo = objType.GetProperty(strArray(0))
If Not propinfo Is Nothing Then
If strArray.Count > 1 Then
Dim dotIndex = propertyName.IndexOf(".")
Dim propName = propertyName.Substring(IIf(dotIndex >= 0, dotIndex + 1, 0))
retval = GetPropertyType(propinfo.PropertyType, propName)
Else
retval = propinfo.PropertyType
End If
Else
Throw New Exception("Property name error!!!")
End If
Else
retval = objType
End If
Return retval
End Function

Public Shared Function GetPropertyValue(ByVal obj As Object, _
ByVal propertyName As String, _
Optional ByVal index As Integer = -1) As Object
Dim retval As Object = Nothing
Dim strArray = propertyName.Split(".")
If strArray.Count > 0 Then
Dim objType As Type = obj.GetType()
Dim propinfo As PropertyInfo = objType.GetProperty(strArray(0))
If Not propinfo Is Nothing Then
If strArray.Count > 1 Then
Dim dotIndex = propertyName.IndexOf(".")
Dim propName = propertyName.Substring(IIf(dotIndex >= 0, dotIndex + 1, 0))
retval = GetPropertyValue(propinfo.GetValue(obj, Nothing), propName, index)
Else
If index >= 0 Then
Dim indexes As Object()
ReDim indexes(0)
indexes(0) = index
retval = propinfo.GetValue(obj, indexes)
Else
retval = propinfo.GetValue(obj, Nothing)
End If
End If
Else
Throw New Exception("Property name error!!!")
End If
Else
retval = obj
End If
Return retval
End Function
 

24 aprile 2008

Oggi sono su ASPITALIA.COM

Esce oggi sul portale AspItalia un mio tip in VB.NET dal titolo 'Un ExpressionBuilder di ASP.NET per recuperare le immagini all'interno del tema corrente'.

Per leggere il tipi cliccate qui

 

MIX Essentials 08: il giorno dopo

Ieri ho dormito poco, ho preso due aerei entrambi in ritardo (uno dei quali quasi dirottato a Malpensa per la nebbia) e oggi sono attivo e sveglio come lo zerbino di casa!

Ma ne è valsa la pena!!

Pur non essendo uno sviluppatore prettamente web, la giornata è stata ricca di spunti e "ganci" per approfondire.

Innanzitutto grande Steve Ballmer, carismatico, verace e sicuramente una figura imponente (e non solo dal punto di vista fisico).

In un ora ci ha descritto cosa intende per web 2.0 e come vede il futuro del web nei prossimi anni e, a dargli retta, di lavoro ce ne sarà.

Bisognerà solo imboccare la giusta strada e crederci.

La mattina di fatto ci ha proposto dei case study (interessanti ma non come papà Steve) mentre il pomeriggio ha visto Silverlight 2.0, Windows Live e Silverlight per Mobile.

Decisamente interessante la sessione su Silverlight 2.0 con tanto codice scritto e consolidamento di quanto già c'è.

Piena di prosettive la seconda sessione su Windows Live che ci ha fornito spunti per integrare nuovi servizi nelle nostre applicazioni (anche qui tanto codice)

La terza sessione, invece, è stata da "sguardo da mucca che vede passare il treno", Tutti incollati allo schermo, meravigliati (o, almeno, io ero meravigliato) da Silverlight per Mobile (che ricordiamo appena sfornata) con effetti e vettorialità su un normale smartphone.

E siamo solo all'inizio!!!

11 aprile 2008

Su Computer Programming il reportage dell'evento Microsoft {Heroes}

E' uscito sul numero 177 di Computer Programming il mio articolo/reportage sull'evento Microsoft di lancio dei prodotti 2008 (Visual Studio, SQL Server e Windows Server):

 

Cover

 

29 febbraio 2008

Heroes: gli eroi sono {qui} (parte II)

Giornata tutta dedicata agli aspetti (tanti) tecnici del lancio dei prodotti 2008 di casa Microsoft.

 Ingresso East End STudios

Ci vorrebbero decine di post per elencare tutte le novità e le migliorie apportate nei nuovi prodotti presentati.

Tanto per cominciare ho avuto la possibilità (visto che non ho la possibilità di sdoppiarmi) di seguire le sole sessioni MSDN (quelle dedicate agli sviluppatori).

La parte da padrone, secondo il mio modesto avviso, l'ha fatta LINQ.

LINQ to object, LINQ to SQL e le altre sfaccettature della nuova "metodologia" di accesso ai dati sono comparse in quasi tutte le sessioni, confermando, in questo modo che rappresenta un pilastro per gli sviluppi futuri.

Personalmente sono rimasto favorevolmente colpito dalla versatilità, espandibilità e, manutenibilità che conferisce al codice.

Proverò ad inserirlo in maniera sensata e ragionata nei prossimi progetti.

Ottimo Visual Studio 2008 soprattutto per la parte di debug con la possibilità di effettuare debug anche sul javascript delle pagine ASP.NET e nelle applicazioni office (perfino nelle macro VBA) e nei numerosi wizard che semplificano la vita (uno su tutti quello per la realizzazioni di servizi WCF consumabili da javascript).

Infine, interessante anche la parte relativa a Windows Presentation Foundation, soprattutto in chiave Silverlight 2.0 (sempre che, quest'ultimo, mantenga la promessa di avere al suo interno la maggior parte di WPF) e Workflow Foundation (a me nota solo di nome fino ad ora) che riveste un uolo chiave per le applicazioni che si basano su workflow (praticamente il 90%).

In conclusione, un ottimo evento con tanta carne da mettere al fuoco e poco tempo per farlo. Ora si torna a casa a sperimentare ciò che si è visto attendendo che capiti qualche progetto su cui sperimentare il tutto!!

 

Heroes: gli eroi sono {qui} (parte I)

Prima giornata densa di appuntamenti per l'evento lancio dei prodotti della famiglia 2008.

Microsoft aggredisce il mondo enterprise fornendo una piattaforma che nelle intenzioni della casa di Redmond dovrebbe puntare su 4 obiettivi fondamentali

  • Sicurezza e Affidabilità
  • Virtualizzazione
  • Web e Produttività dello sviluppo
  • Business Intelligence

Tante le novità previste sia dal punto di vista server che dal punto di vista linguaggi di sviluppo.

IMAGE_00016

Oggi ci saranno le sessioni tecniche, quelle che tutti aspettiamo!

A domani per il resoconto!