Visualizzazione post con etichetta Sviluppo. Mostra tutti i post
Visualizzazione post con etichetta Sviluppo. 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 gennaio 2009

Pubblicato un articolo su ioProgrammo di febbraio

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

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:



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!!!

 

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!

18 gennaio 2008

WPF: MSDN Reader e SDK per RSS

Breve post per girare un post del Blog MSDN che annuncia il rilascio del reader per MSDN Magazine, sviluppato con WPF e dell'SDK per realizzare i propri client RSS:

Reader MSDN Magazine
SDK per Client RSS

29 agosto 2007

VB.NET : Memorizzare un file qualsiasi all'interno di un assembly

Il Framework .NET offre la possibilità di memorizzare, all'interno di un assembly, un qualunque tipo di file.

Per fare ciò è necessario:

1) importare il file all'interno del progetto utilizzando il menù Progetto\Aggiungi elemento esistente;

2) selezionare il file all'interno del solution explorer e selezionare il menù contestuale Proprietà;

3) modificare la proprietà Operazione di Generazione in Risorsa Incorporata;

A questo punto il file "viaggia" assieme all'assembly compilato.

Per recuperare a run-time il file è sufficiente utilizzare il seguente pezzo di codice:


  .
  .
  Dim asm As System.Reflection.Assembly
  Dim st As System.IO.Stream
  Dim bytearray As Byte()
  asm = Reflection.Assembly.GetExecutingAssembly
  st = asm.GetManifestResourceStream("<RootNamespace>.file.ext")
  ReDim bytearray(CInt(st.Length) - 1)
  st.Read(bytearray, 0, CInt(st.Length))
  st.Close()
  .
  .


<RootNameSpace> è il nome del namespace root dell'assembly mentre file.ext è il nome del file inserito nel progetto.

La chiamata del metodo GetManifestResourceStream() può sollevare un'eccezione se il file supera la dimensione di 2GB.

Se il file non esiste all'interno dell'assembly o il nome del namespace è sbagliato, si ottiene un'eccezione nel momento in cui si effettua la chiamata al metodo GetManifestResourceStream().

Questa tecnica è utile se si vogliono memorizzare icone o immagini delle nostre applicazioni.
La seguente Function recupera un'icona memorizzata nell'assembly:


Private Shared Function GetResourceIcon(ByVal rootNamespace As String, _
    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

04 giugno 2007

Le novità di .NET Framework 3.5

Inserisco questo post solo per comunicare un interessante articolo uscito su ASPItalia.com riguardante le novità del .NET Framework 3.5 di prossima uscita.

Consiglio di leggerlo perché da un’idea di cosa troveremo di nuovo e del perché sono state fatte determinate scelte:

 

http://www.winfxitalia.com/articoli/netfx3.5/clr.aspx

28 maggio 2007

VB.NET : ExpressionBuilder per recuperare le immagini all'interno del tema corrente.

Il problema che cerca di risolvere la classe che vi presento è il seguente: supponiamo di volere che una proprietà di un controllo che prevede l'url di una immagine, sia valorizzata con l'url di una immagine contenuta nel tema corrente della pagina aspx.
In parole povere:

<img src="Images/immagine.gif" />

dove Images/immagine.gif deve essere presa dalla cartella Images del tema corrente e non dalla cartella Images della root.
Per risolvere il problema ho realizzato un semplice Expression Builder:

<ExpressionPrefix("ThemeImage")> _
Public Class ThemeImageExpressionBuilder
  Inherits System.Web.Compilation.ExpressionBuilder

  Public Overrides Function GetCodeExpression(ByVal entry As System.Web.UI.BoundPropertyEntry, _
      ByVal parsedData As Object, _
      ByVal context As System.Web.Compilation.ExpressionBuilderContext) As System.CodeDom.CodeExpression
    Dim metodo As CodeMethodInvokeExpression = New CodeMethodInvokeExpression()
    metodo.Method.TargetObject = New CodeTypeReferenceExpression("ThemeImageExpressionBuilder")
    metodo.Method.MethodName = "GetAbsoluteImageURL"
    metodo.Parameters.Add(New CodePrimitiveExpression(entry.Expression))
    Return metodo
  End Function

  ''' Restituisce il path dell'immagine comprensivo di tema
  Public Shared Function GetAbsoluteImageURL(ByVal relativeImageURL As String) As String
    Dim retURL As String = String.Empty
    If TypeOf HttpContext.Current.Handler Is UI.Page Then
      Dim page As UI.Page = CType(HttpContext.Current.Handler, UI.Page)
      Dim themeName As String = page.Theme
      If themeName <> "" Then
        retURL = System.IO.Path.Combine("~/App_Themes/" + themeName, relativeImageURL)
      Else
        retURL = relativeImageURL
      End If
    End If
    Return retURL
  End Function

  Public Overrides ReadOnly Property SupportsEvaluate() As Boolean
    Get
      Return True
    End Get
  End Property
End Class

Configurando l'utilizzo di questo ExpressionBuilder all'interno del web.config:

<compilation debug="true">
  <expressionBuilders>
    <add expressionPrefix="ThemeImage" type="ThemeImageExpressionBuilder"/>
  </expressionBuilders>

Possiamo scrivere, all'interno delle nostre pagine aspx:

<img src="<%& ThemeImage: Images/immagine.gif %>" />

20 aprile 2007

VB.NET : Determinare se un oggetto ha una determinata proprietà

La seguente funzione consente di sapere se un oggetto obj, passato come argomento, dispone di una proprietà chiamata propertyName eventualmente del tipo propertyType:


Public Function ObjectHasProperty(ByVal obj As Object, ByVal propertyName As String, Optional ByVal propertyType As Type = Nothing) As Boolean
  Dim retVal As Boolean = False
  Dim objType As Type = obj.GetType()
  Dim propinfo As System.Reflection.PropertyInfo = objType.GetProperty(propertyName)
  If Not propinfo Is Nothing Then
    If propertyType Is Nothing Or propinfo.PropertyType.IsAssignableFrom(propertyType) Then
      retVal = True
    End If
  End If
  Return retVal
End Function

06 aprile 2007

VB.NET : Impostare il focus su di un controllo della pagina ASPX

La seguente funzione consente di impostare il focus su di un ben determinato controllo al momento del caricamento della pagina ASPX.
Può rendersi utile se abbiamo una pagina web con un controllo che deve essere attivo al momento del caricamento della pagina (ad esempio il campo per la ricerca o il login).



Private Sub SetDefaultControlFocus(ByVal ctrl As Control)
  Dim formName As String
  Dim c As Control = ctrl.Parent
  While (Not (TypeOf c Is System.Web.UI.HtmlControls.HtmlForm))
    c = c.Parent
  End While

  If TypeOf c Is System.Web.UI.HtmlControls.HtmlForm Then
    formName = c.ClientID
  Else
    formName = "forms[0]"
  End If

  Dim jsString As New StringBuilder
  With jsString
    .Append("")
  End With
  Me.RegisterStartupScript("defaultControlFocusScript", jsString.ToString())
End Sub

30 gennaio 2007

Recuperare l'URL della root di un sito

La function che propongo questa volta permette di recuperare, in una qualsiasi pagina aspx, l'indirizzo URL della root del sito che la ospita.


Protected Function GetSiteRoot() As String
 Dim virtualPathItems As String() = Me.Request.Path.Split("/")
 Dim urlPathItems As String() = Me.Request.Url.AbsoluteUri.Split("/")
 Dim siteRoot As New StringBuilder
 For i As Int16 = 0 To urlPathItems.Length - 1
  siteRoot.Append(urlPathItems(i))
  If String.Compare(urlPathItems(i), virtualPathItems(1)) = 0 Then
   Exit For
  Else
   siteRoot.Append("/")
  End If
 Next
 Return siteRoot.ToString()
End Function