Alessandro Del Sole's Blog

{ A programming space about Microsoft® .NET® }
posts - 1908, comments - 2047, trackbacks - 352

My Links

News

Your host

This is me! Questo spazio è dedicato a Microsoft® .NET®, di cui sono molto appassionato :-)

Cookie e Privacy

Disabilita cookie ShinyStat

Microsoft MVP

My MVP Profile

Microsoft Certified Professional

Microsoft Specialist

Xamarin Certified Mobile Developer

Il mio libro su VB 2015!

Pre-ordina il mio libro su VB 2015 Pre-ordina il mio libro "Visual Basic 2015 Unleashed". Clicca sulla copertina per informazioni!

Il mio libro su WPF 4.5.1!

Clicca sulla copertina per informazioni! E' uscito il mio libro "Programmare con WPF 4.5.1". Clicca sulla copertina per informazioni!

These postings are provided 'AS IS' for entertainment purposes only with absolutely no warranty expressed or implied and confer no rights.
If you're not an Italian user, please visit my English blog

Le vostre visite

I'm a VB!

Guarda la mia intervista a Seattle

Follow me on Twitter!

Altri spazi

GitHub
I miei progetti open-source su GitHub

Article Categories

Archives

Post Categories

Image Galleries

Privacy Policy

Serializzazione Xaml in .NET 4.0

A dire il vero la tecnica che descriverò in questo post non è una vera e propria novità di .NET 4.0 (anche se la illustrerò con Visual Basic 2010), tuttavia questa nuova versione del Framework introduce comunque qualcosa di nuovo. In primo luogo, c’è un nuovo assembly che si chiama System.Xaml.dll e che si occupa di fornire servizi per processare e per il parsing dello XAML in applicazioni WPF. Molto di ciò che era parte dell’assembly WindowsBase.dll al riguardo di XAML, ora è in questa nuova libreria che espone un namespace System.Xaml le cui classi verranno utilizzate in questo post.

 

Ora veniamo a noi; nel corso degli anni la serializzazione nello sviluppo .NET ha subito diverse modifiche, non tanto nelle tecniche di base, quanto nelle novità introdotte a supporto di tecnologie come WCF e Entity Framework. Nell’ambito di queste novità, ritroviamo la Xaml Serialization ossia la possibilità di serializzare i nostri dati sotto forma di markup XAML, tecnica che ha molteplici vantaggi: innanzitutto la possibilità di serializzare, anche interi grafi di oggetti, sotto forma Xml; XAML è comunque Xml, quindi portabile. In secondo luogo, la possibilità di serializzare con facilità gli oggetti WPF; infine, la possibilità di utilizzare tale tecnica nei confronti di oggetti .NET “classici” anche al di fuori di applicazioni WPF.

 

Per la demo che segue ho utilizzato Visual Studio 2010 Beta 1 e avrò la scusa per mostrare alcune novità sintattiche di VB 2010. Detto questo, creiamo un progetto per la Console e aggiungiamo un riferimento all’assembly System.Xaml.

Ora supponiamo di avere una classe Customer così definita:

 

Public Class Customer

    'Uso le auto-implemented properties :-)

    Public Property CustomerID As String

    Public Property CompanyName As String

    Public Property Orders As List(Of Order)

End Class

 

Tale classe espone una proprietà Orders di tipo List(Of Order). In questo modo possiamo simulare un grafo di oggetti. La classe Order è così definita (in modo semplificato):

 

Public Class Order

    Public Property OrderID As Integer

    Public Property OrderDate As Date

    Public Property ShipAddress As String

End Class

 

Ora ci servono alcune istanze di oggetti per una simulazione. In primo luogo, creiamo due istanze della classe Order. Notate come il codice sfrutti gli object initializer per l’inizializzazione in linea:

 

        Dim order1 As New Order With {.OrderDate = Date.Today, .OrderID = 1, .ShipAddress = "Somewhere"}

        Dim order2 As New Order With {.OrderDate = Date.Today, .OrderID = 2, .ShipAddress = "Somewhere else"}

 

Ora creiamo un’istanza della classe Customer e popoliamo la sua proprietà Orders con una collezione di Order. Sfruttiamo una nuova feature di VB 2010, ossia i collection initializer, per inizializzare la collezione direttamente in istanza:

 

        Dim cust As New Customer With {.CustomerID = "DELSO", .CompanyName = "Del Sole",

                                       .Orders = New List(Of Order) From {order1, order2}}

 

Per serializzare l’oggetto cust ci serve uno stream (su disco o in memoria) per poi richiamare il metodo condiviso XamlServices.Save, come nel codice seguente:

 

        'Direttive Imports System.Xaml, System.IO richieste

        'Serialize

        Using target As New FileStream("C:\temp\CustomerData.xaml", FileMode.Create)

            XamlServices.Save(target, cust)

        End Using

 

Il metodo Save richiede, come argomenti, lo stream di destinazione e l’oggetto da serializzare. Se andiamo ad esaminare il contenuto del file .Xaml generato, noteremo la seguente forma:

 

<Customer CompanyName="Del Sole"

    CustomerID="DELSO"

    xmlns="clr-namespace:XamlSerialization;assembly=XamlSerialization"

    xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Customer.Orders>

        <scg:List x:TypeArguments="Order" Capacity="4">

            <Order OrderDate="2009-10-11T00:00+02:00" OrderID="1" ShipAddress="Somewhere"/>

            <Order OrderDate="2009-10-11T00:00+02:00" OrderID="2" ShipAddress="Somewhere else"/>

        </scg:List>

    </Customer.Orders>

</Customer>

 

 

Oltre al classico namespace Xml che punta allo schema per lo Xaml, notate come si faccia richiamo al namespace System.Collections.Generic; ciò è perché noi abbiamo fatto uso dei generics. Il risultato della serializzazione è abbastanza semplice da capire. L’oggetto è stato serializzato come Xaml e gli oggetti da esso referenziati sono stati rappresentati in un nodo Customer.Orders, completando la serializzazione del grafo. Notate come il tag scg:List indichi che il suo contenuto deve essere rappresentato, in deserializzazione, da una lista generica.

 

Deserializzare lo XAML è altrettanto semplice. Si invoca il metodo XamlServices.Load, come nel codice seguente:

 

        'Deserialize

        Using source As New FileStream("C:\temp\CustomerData.xaml", FileMode.Open)

            'Il metodo restituisce Object, conversione richiesta

            Dim myCustomer As Customer = CType(XamlServices.Load(source), Customer)

 

            For Each ord In myCustomer.Orders

                Console.WriteLine(ord.ShipAddress)

            Next

        End Using

 

 

Il ciclo For..Each ha il solo scopo di dimostrare che la deserializzazione ha avuto successo. Ricordate che, se serializzate generics, questi devono implementare almeno IList o IDictionary. Ovviamente questo è solo un esempio ma la tecnica può essere molto raffinata e anche complessa. Sicuramente propone uno scenario decisamente più ampio, se pensiamo al suo utilizzo anche in applicazioni WPF.

 

Alessandro

Print | posted on lunedì 12 ottobre 2009 01:12 | Filed Under [ .NET Framework Visual Basic Windows Presentation Foundation ]

Powered by:
Powered By Subtext Powered By ASP.NET