Angella Andrea

Blog tecnico sulla piattaforma .NET e lo sviluppo software.
posts - 83, comments - 90, trackbacks - 62

My Links

News




Sto leggendo:

Archives

Post Categories

Siti web realizzati

Siti web tecnici

lunedì 24 novembre 2008

Intervista al Team Leader di JQuery

Su HTML.it è possibile trovare la traduzione in italiano dell'interessante intervista a John Resig che è il Team Leader del framework JQuery.

Può essere sicuramente interessante valutare l'acquisto del suo libro Pro Javascript Techniques e di un altro intitolato Secrets of the Javascript Ninja che sarà disponibile il prossimo anno.

Nel frattempo sono in attesa del libro JQuery in Action che sono molto curioso di leggere. Gian Maria è colpa tua :-)

 

jquery

posted @ lunedì 24 novembre 2008 22.37 | Feedback (2) | Filed Under [ Javascript ]

martedì 18 novembre 2008

[70-536] GZipStream class, DeflateStream class and Isolated Storage

Area di riferimento

- Implementing serialization and input/output functionality in a .NET Framework application (18 percent)
   - Compress or decompress stream information in a .NET Framework application and improve the security of application data by using isolated storage
      - May include but is not limited to: IsolatedStorageFile class, IsolatedStorageFileStream class;
      - DeflateStream class; GZipStream class


GZipStream and DeflateStream classes

La classi GZipStream e DeflateStream permettono di comprimere dati utilizzando il famoso algoritmo di compressione Gzip. Conviene utilizzare la classe GZipStream nel caso in cui si intenda distribuire i file in modo che questi possano essere decompressi utilizzando l'ampiamente diffuso tool gzip.

Queste classi si trovano nel namespace System.IO.Compression e il loro utilizzo è molto semplice.

class Program { static void Main(string[] args) { File.WriteAllText("source.txt", "Il contenuto di questo file verra' compresso."); // File compression using (FileStream sourceFile = File.Open("source.txt", FileMode.Open)) { using (FileStream destinationFile = File.Open("destination.dat", FileMode.Create)) { using (GZipStream comp = new GZipStream(destinationFile, CompressionMode.Compress)) { int b; while ((b = sourceFile.ReadByte()) != -1) { comp.WriteByte((byte)b); } } } } // File decompression using (FileStream sourceFile = File.Open("destination.dat", FileMode.Open)) { using (FileStream destinationFile = File.Open("new-source.txt", FileMode.Create)) { using (GZipStream decomp = new GZipStream(sourceFile, CompressionMode.Decompress)) { int b; while ((b = decomp.ReadByte()) != -1) { destinationFile.WriteByte((byte)b); } } } } Console.WriteLine(File.ReadAllText("new-source.txt")); Console.ReadKey(); } }

Isolated Storage

L'Isolated Storage è un repository all'interno del quale è possibile leggere e scrivere dati in maniera sicura indipendentemente dai privilegi di cui disponde il codice.

La prima cosa da fare quando si lavora con l'isolated storage è scegliere l'ambito in cui saranno memorizzati i dati:

  • Assembly/Machine : Si utilizza questo ambito per persistere dati a livello di applicazione.
  • Assembly/User : Si utilizza questo ambito per persistere dati a livello di utente. Ogni utente della macchina avrà le sue impostazioni specifiche.
  • ...

L'utilizzo dell'Isolated Storage ruota intorno alle classi IsolatedStorageFile e IsolatedStorageFileStream. E' inoltre possibile utilizzare l'attributo IsolatedStorageFilePermission per specificare il permesso di accedere all'Isolated Storage e impostare altri parametri come ad esempio la quota massima di spazio da associare a ciascun utente.

 

[IsolatedStorageFilePermission(SecurityAction.Demand, UserQuota=256)] class Program { static void Main(string[] args) { // Assembly/Machine Scope - Writing data IsolatedStorageFile applicationStorage = IsolatedStorageFile.GetMachineStoreForAssembly(); IsolatedStorageFileStream applicationStream = new IsolatedStorageFileStream("application-settings.dat", FileMode.Create, applicationStorage); using (StreamWriter writer = new StreamWriter(applicationStream)) { writer.Write("Informazioni a livello applicazione"); } // User/Machine Scope - Writing data IsolatedStorageFile userStorage = IsolatedStorageFile.GetUserStoreForAssembly(); IsolatedStorageFileStream userStream = new IsolatedStorageFileStream("user-settings.dat", FileMode.Create, userStorage); using (StreamWriter writer = new StreamWriter(userStream)) { writer.Write("Informazioni a livello utente in user-settings.dat"); } userStorage.CreateDirectory("folder"); userStream = new IsolatedStorageFileStream(@"folder\user-settings.dat", FileMode.Create, userStorage); using (StreamWriter writer = new StreamWriter(userStream)) { writer.Write("Informazioni a livello utente in folder\\user-settings.dat"); } // Reading data Console.WriteLine("Directories :"); foreach (string directory in userStorage.GetDirectoryNames("*")) { Console.WriteLine(directory); } Console.WriteLine("Files *.dat :"); foreach (string file in userStorage.GetFileNames("*.dat")) { Console.WriteLine(file); } Console.ReadKey(); } }

posted @ martedì 18 novembre 2008 14.07 | Feedback (0) | Filed Under [ Exam 70-536 Application Development Foundation ]

[70-536] - File System classes and Streams

Area di riferimento

- Implementing serialization and input/output functionality in a .NET Framework application (18 percent)
   - Access files and folders by using the File System classes
      - May include but is not limited to: File class and FileInfo class; Directory class and DirectoryInfo class;
      - DriveInfo class and DriveType enumeration; FileSystemInfo class and FileSystemWatcher class; Path class;
      - ErrorEventArgs class and ErrorEventHandler delegate; RenamedEventArgs class and RenamedEventHandler delegate
   - Manage byte streams by using Stream classes
      - May include but is not limited to: FileStream class; Stream class; MemoryStream; BufferedStream class
   - Manage .NET Framework application data by using Reader and Writer classes
      - May include but is not limited to: StringReader class and StringWriter class; TextReader class and TextWriter class;
      - StreamReader class and Stream Writer class; BinaryReader class and BinaryWriter class


File System classes

Il framework .NET offre numerose classi che permettono l'accesso al file system.

La classe DriveInfo permette di ottenere informazioni relative ai drive presenti sulla macchina. La classe File permette di effettuare alcune tipiche operazioni sui file come la copia, la creazione e la cancellazione. Le classi FileInfo e DirectoryInfo derivano da FileSystemInfo e consentono di accedere a diverse informazioni relative a file e directory. Utilizzando queste classi inoltre è estremamente semplice navigare attraverso il file system ottenendo l'elenco dei file presenti all'interno di una directory e l'elenco di directory presenti all'interno di un'altra directory. La classe Path fornisce un valido supporto per estrapolare informazioni relative ad un path e soprattutto offre una comoda funzione per combinare due path fra loro.

Grazie all'interessantissima classe FileSystemWatcher è inoltre possibile monitorare in tempo reale le modifiche che vengono compiute all'interno di una particolare cartella semplicemente gestendo opportuni eventi.

Di seguito riporto un pò di codice che utilizza tutte queste classi. Il loro utilizzo è molto intuitivo per questo non ritengo necessaria alcuna ulteriore spiegazione.

1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Console.WriteLine("Drive\n"); 6 7 DriveInfo driveInfo = new DriveInfo("C"); 8 Console.WriteLine("Name: {0}", driveInfo.Name); 9 Console.WriteLine("TotalSize: {0} bytes", driveInfo.TotalSize); 10 Console.WriteLine("TotalFreeSpace: {0} bytes", driveInfo.TotalFreeSpace); 11 Console.WriteLine("AvailableFreeSpace: {0} bytes", driveInfo.AvailableFreeSpace); 12 Console.WriteLine("DriveFormat: {0}", driveInfo.DriveFormat); 13 Console.WriteLine("DriveType: {0}", driveInfo.DriveType); 14 Console.WriteLine("VolumeLabel: {0}", driveInfo.VolumeLabel); 15 16 Console.WriteLine("\nFile:\n"); 17 18 File.AppendAllText("file1.txt", "Ciao a tutti da Andrea", Encoding.ASCII); 19 File.Copy("file1.txt", "file2.txt", true); 20 21 FileInfo file2Info = new FileInfo("file2.txt"); 22 Console.WriteLine("CreationTime: {0}", file2Info.CreationTime); 23 Console.WriteLine("LastWriteTime: {0}", file2Info.LastWriteTime); 24 Console.WriteLine("DirectoryName: {0}", file2Info.DirectoryName); 25 Console.WriteLine("Exists: {0}", file2Info.Exists); 26 Console.WriteLine("Extension: {0}", file2Info.Extension); 27 Console.WriteLine("FullName: {0}", file2Info.FullName); 28 Console.WriteLine("Name: {0}", file2Info.Name); 29 Console.WriteLine("IsReadOnly: {0}", file2Info.IsReadOnly); 30 Console.WriteLine("Length: {0}", file2Info.Length); 31 32 Console.WriteLine("\nDirectory:\n"); 33 34 DirectoryInfo dir2Info = file2Info.Directory; 35 Console.WriteLine("CreationTime: {0}", dir2Info.CreationTime); 36 Console.WriteLine("FullTime: {0}", dir2Info.FullName); 37 Console.WriteLine("Exists: {0}", dir2Info.Exists); 38 Console.WriteLine("LastAccessTime: {0}", dir2Info.LastAccessTime); 39 Console.WriteLine("LastWriteTime: {0}", dir2Info.LastWriteTime); 40 41 dir2Info.CreateSubdirectory("folder1"); 42 dir2Info.CreateSubdirectory("folder2"); 43 dir2Info.CreateSubdirectory("folder3"); 44 45 Console.WriteLine("Files in folder: "); 46 foreach (FileInfo fileInfo in dir2Info.GetFiles()) 47 { 48 Console.WriteLine("\t{0}", file2Info.Name); 49 } 50 51 Console.WriteLine("Directory in folder: "); 52 foreach (DirectoryInfo dirInfo in dir2Info.GetDirectories()) 53 { 54 Console.WriteLine("\t{0}", dirInfo.Name); 55 } 56 57 if (Directory.Exists("folder1")) 58 { 59 Directory.Delete("folder1"); 60 } 61 Directory.Delete("folder2"); 62 new DirectoryInfo("folder3").Delete(); 63 file2Info.Delete(); 64 65 Console.WriteLine("\nPath: c:\\prova\\file.txt \n"); 66 Console.WriteLine("GetDirectoryName: {0}", Path.GetDirectoryName(@"c:\prova\file.txt")); 67 Console.WriteLine("GetExtension: {0}", Path.GetExtension(@"c:\prova\file.txt")); 68 Console.WriteLine("GetFileName: {0}", Path.GetFileName(@"c:\prova\file.txt")); 69 Console.WriteLine("GetFileNameWithoutExtension: {0}", Path.GetFileNameWithoutExtension(@"c:\prova\file.txt")); 70 Console.WriteLine("GetFullPath: {0}", Path.GetFullPath(@"c:\prova\file.txt")); 71 Console.WriteLine("GetPathRoot: {0}", Path.GetPathRoot(@"c:\prova\file.txt")); 72 Console.WriteLine("GetRandomFileName: {0}", Path.GetRandomFileName()); 73 Console.WriteLine("GetTempPath: {0}", Path.GetTempPath()); 74 Console.WriteLine("GetTempFileName: {0}", Path.GetTempFileName()); 75 76 Console.WriteLine("Combine: {0}", Path.Combine("c:\\prova1", "prova2\\file.txt")); 77 78 Console.WriteLine("\nFileSystemWatcher: \n"); 79 80 Directory.CreateDirectory("folder"); 81 FileSystemWatcher fsWatcher = new FileSystemWatcher("folder"); 82 fsWatcher.Created += new FileSystemEventHandler(fsWatcher_Created); 83 fsWatcher.Deleted += new FileSystemEventHandler(fsWatcher_Deleted); 84 fsWatcher.Changed += new FileSystemEventHandler(fsWatcher_Changed); 85 fsWatcher.Renamed += new RenamedEventHandler(fsWatcher_Renamed); 86 fsWatcher.Error += new ErrorEventHandler(fsWatcher_Error); 87 88 fsWatcher.EnableRaisingEvents = true; 89 90 Console.ReadKey(); 91 } 92 93 static void fsWatcher_Error(object sender, ErrorEventArgs e) 94 { 95 Console.WriteLine("FileSystemWatcher Error\n"); 96 } 97 98 static void fsWatcher_Changed(object sender, FileSystemEventArgs e) 99 { 100 Console.WriteLine("ChangeType: {0}", e.ChangeType); 101 Console.WriteLine("FullPath: {0}", e.FullPath); 102 Console.WriteLine("Name: {0}\n", e.Name); 103 } 104 105 static void fsWatcher_Renamed(object sender, RenamedEventArgs e) 106 { 107 Console.WriteLine("ChangeType: {0}", e.ChangeType); 108 Console.WriteLine("FullPath: {0}", e.FullPath); 109 Console.WriteLine("Name: {0}", e.Name); 110 Console.WriteLine("OldFullPath: {0}", e.OldFullPath); 111 Console.WriteLine("OldName: {0}\n", e.OldName); 112 } 113 114 static void fsWatcher_Deleted(object sender, FileSystemEventArgs e) 115 { 116 Console.WriteLine("ChangeType: {0}", e.ChangeType); 117 Console.WriteLine("FullPath: {0}", e.FullPath); 118 Console.WriteLine("Name: {0}\n", e.Name); 119 } 120 121 static void fsWatcher_Created(object sender, FileSystemEventArgs e) 122 { 123 Console.WriteLine("ChangeType: {0}", e.ChangeType); 124 Console.WriteLine("FullPath: {0}", e.FullPath); 125 Console.WriteLine("Name: {0}\n", e.Name); 126 } 127 }

Streams

Gli stream realizzano un meccanismo unificato per gestire l'accesso sequenziale e random ai dati. La classe astratta Stream fornisce l'interfaccia di base e l'implementazione per tutti gli strem all'interno del Framework. Quando si apre un file viene restituito un oggetto di tipo FileStream che offre una interfaccia di basso livello per l'accesso al file. Le classi StreamReader e StreamWriter facilitano la lettura e la scrittura di file di testo. Le classi BinaryReader e BinaryWriter invece permettono la lettura e la scrittura di dati binari in modo più semplice del dover lavorare direttamente su vettori di byte.

Quando si lavora con piccoli file di testo è possibile utilizzare le funzioni File.WriteAllText e File.ReadAllText rispettivamente per scrivere un file di testo a partire da una stringa e per ottenere il contenuto di un file di testo all'interno di una stringa.

La classe MemoryStream fornisce le funzionalità per creare stream in memoria. Le classi StringReader e StringWriter invece svolgono le stesse funzionalità delle classi StreamReader e StreamWriter solo che la sorgente dati associata è una stringa al contrario di un file ( le classi astratte da cui derivano sono TextReader e TextWriter che implementano le funzionalità di base per la lettura e scrittura di testo).

Ecco un pò di codice dimostrativo:

1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Console.WriteLine("*** Text Streams: ***\n"); 6 7 FileStream fs = File.Open("file.txt", FileMode.Create); 8 9 byte[] bytesTitolo = new ASCIIEncoding().GetBytes("Titolo del file\r\n\r\n"); 10 fs.Write(bytesTitolo, 0, bytesTitolo.Length); 11 12 using (StreamWriter sw = new StreamWriter(fs)) 13 { 14 sw.WriteLine("Ciao a tutti"); 15 sw.WriteLine("il mio nome è Andrea"); 16 } 17 18 using (StreamReader sr = File.OpenText("file.txt")) 19 { 20 while (!sr.EndOfStream) 21 { 22 Console.WriteLine(sr.ReadLine()); 23 } 24 } 25 26 Console.WriteLine(); 27 28 File.WriteAllText("file2.txt", "Prima riga del file2\r\nSeconda riga del file2"); 29 Console.WriteLine(File.ReadAllText("file2.txt")); 30 31 Console.WriteLine("\n*** Binary Streams: ***\n"); 32 33 fs = File.Open("file3.dat", FileMode.Create); 34 using (BinaryWriter bw = new BinaryWriter(fs)) 35 { 36 bw.Write('A'); 37 bw.Write(true); 38 bw.Write(12.45); 39 bw.Write("Ciao"); 40 } 41 fs = File.Open("file3.dat", FileMode.Open); 42 using (BinaryReader br = new BinaryReader(fs)) 43 { 44 Console.WriteLine(br.ReadChar()); 45 Console.WriteLine(br.ReadBoolean()); 46 Console.WriteLine(br.ReadDouble()); 47 Console.WriteLine(br.ReadString()); 48 } 49 50 Console.WriteLine("\n*** Memory Streams: ***\n"); 51 52 MemoryStream ms = new MemoryStream(); 53 using (StreamWriter sw = new StreamWriter(ms)) 54 { 55 sw.WriteLine("Scrivo su uno stream in memoria."); 56 sw.Flush(); 57 58 using (fs = File.Open("file.txt", FileMode.Append)) 59 { 60 ms.WriteTo(fs); 61 } 62 } 63 64 Console.ReadKey(); 65 } 66 }

Infine è importante citare la classe BufferedStream che permette di migliorare le performance implementando un meccanismo di lettura e scrittura bufferizzato.

posted @ martedì 18 novembre 2008 13.51 | Feedback (0) | Filed Under [ Exam 70-536 Application Development Foundation ]

sabato 8 novembre 2008

DotNetToscana: il principio.

Io, Andrea Angella, sono diventato un membro della community UgiDotNet il giorno 9 Agosto 2007 con il post Finalmente il mio blog tecnico. Circa un mese dopo alle ore 10:33 del giorno 11 Settembre 2007 (gli attentati fortunatamente non centrano niente) arriva nella mia casella di posta elettronica una mail da parte di Matteo Baglini.

Riporto il testo integrale di questa "storica" mail:

"Ciao,
girovagando per il tuo blog ho letto che studi a Pisa quindi non credo che abiti fuori Toscana, spero di non essere invadente ed antipatico, però ti volevo chiedere se hai letto della cena che sto organizzando a Livorno
http://blogs.ugidotnet.org/bmatte/archive/2007/09/06/cacciuccata-a-livorno-il-29-settembre.aspx. Ti va di venire? Se hai già letto l'annuncio e non sei interessato ti va di spiegarmi il perchè? Ti chiedo queste cose perchè ho visto che sono molto pochi i Toscani che hanno risposto all'appello e volevo capire il motivo, in modo da migliorare per un eventuale cena futura e perchè magari anche per questa. Ti chiedo ancora scusa per il disturbo e spero non essere stato scortese.

Ciao Matteo."

 

Ero molto felice di aver ricevuto quella mail ed ho accettato ben volentieri l'invito alla cena. Da quell'istante la mia presenza in UgiDotNet si è concretizzata, sapevo che quello sarebbe stato solo l'inizio di una serie di incontri che mi avrebbero permesso di conoscere personalmente persone eccezionali che condividono la mia forte passione per l'informatica e con le quali avrei potuto passare piacevoli momenti insieme per divertirsi, discutere e condividere esperienze. E così è stato...

La sera del 29 Settembre 2007 ho quindi partecipato alla prima cena con membri di UgiDotNet. Eravamo solamente in 4 (Io, Matteo Baglini, Igor Damiani e Omar Damiani) ma la serata è stata davvero molto piacevole. Verso mezzanotte i due fratelli Damiani (che ringrazio ancora per il forte spirito di community che mi hanno dimostrato) sono tornati a casa. Io avevo il treno verso le ore 3 quindi Matteo ha pensato di portarmi in un pub per fare quattro chiacchere. Dopo avermi presentato la ragazza (al contrario di me lui è felicemente fidanzato) e alcune sue amiche, non abbiamo resistito alla tentazione di tornare a parlare di .NET :-)

E' proprio lì che per la primissima volta abbiamo parlato della possibilità di costruire insieme una nuova community come punto di incontro di studenti e professionisti Microsoft presenti nella regione Toscana. I problemi erano tanti, in primis che eravamo pochi (la cena purtroppo era stata una triste conferma). Matteo pensava in grande, voleva fare le cose con i giusti tempi affinchè tutto non si rivelasse un fallimento, per questo prima di tutto voleva confrontarsi con altri ragazzi delle community regionali. Vedevo in lui una forte motivazione, un'estrema passione per il suo lavoro e soprattutto un incredibile spirito di community. logo_dotnet5

Il giorno 16 Ottobre 2008, ad un anno da quella data, ai Microsoft Days 2008 è stata ufficialmente presentata a Firenze la community DotNetToscana.

DotNetToscana è per sua volontà una associazione no-profit, dove non esistono ruoli ufficiali ma tutto evolve grazie alla passione di ciascun membro. Nonostante questo per me, Matteo Baglini è il Leader naturale del gruppo, colui che ha creduto e reso possibile tutto questo. Oggi è il compleanno di Matteo e questo post è il mio regalo per lui.

Il più grande augurio è che DotNetToscana possa crescere per diventare un punto di riferimento e sicuramente tutti i suoi attuali membri si impegneranno per questo.

Tanti auguri di Buon Compleanno Matteo !
Tanti auguri di Buon Inizio DotNetToscana !

Andrea

posted @ sabato 8 novembre 2008 15.38 | Feedback (3) |

giovedì 6 novembre 2008

"Informatica Industriale" superato alla grande :-)

Questa mattina io e il mio collega Vincenzo abbiamo sostenuto l'esame di Informatica Industriale conseguendo entrambi una votazione pari a 30 e Lode !

L'esame consisteva (in parte) nella realizzazione del progetto di un semplice Sistema Embedded in modo da familiarizzare con la programmazione di microcontrollori. Abbiamo utilizzato il microcontrollore ADuC836 con un core a 8 bit (8052) e realizzato il software in linguaggio C.

Il risultato si chiama Speedy Finger ed è la realizzazione in hardware del semplice gioco del dito più veloce.

Di seguito il logo creato (ovviamente non realizzato da me che di grafica sono molto carente):

image

 

Per l'occasione (come richiesto dai docenti) abbiamo realizzato un video di presentazione disponibile su YouTube anche in alta risoluzione:

 

 

Oggi termina una lunga serie di progetti universitari che ho realizzato insieme a Vincenzo, collega ma soprattuto grande e sincero amico che ringrazio particolarmente per aver reso molto più piacevole (se non divertente) questo ultimo anno accademico.

Adesso personalmente cercherò di sostenere al più presto l'ultimo esame rimastomi per poi iniziare l'avventura della Tesi.

posted @ giovedì 6 novembre 2008 21.07 | Feedback (5) |

sabato 1 novembre 2008

[70-536] - Serialization and Deserialization

Area di riferimento

- Implementing serialization and input/output functionality in a .NET Framework application (18 percent)
    - Serialize or deserialize an object or an object graph by using runtime serialization techniques.
        - May include but is not limited to: Serialization interfaces; Serialization attributes; SerializationEntry structure and SerializationInfo class;
        - ObjectManager class; Formatter class, FormatterConverter class, and FormatterServices class; StreamingContext structure
   - Control the serialization of an object into XML format by using the System.Xml.Serialization namespace.
       - May include but is not limited to: Serialize and deserialize objects into XML format by using the XmlSerializer class; Control serialization by using serialization attributes;
       - Implement XML serialization interfaces to provide custom formatting for XML serialization; Delegates and event handlers provided by the System.Xml.Serialization namespace 
   - Implement custom serialization formatting by using the Serialization Formatter classes. 
       - May include but is not limited to: SoapFormatter; BinaryFormatter class


Serialization and Deserialization

La serializzazione consiste nel trasformare un oggetto in una sequenza di byte che può essere memorizzata o trasferita tra diverse applicazioni.

Affinchè un tipo possa essere serializzato è necessario decorarlo con l'attributo [Serializable]. Se non non si vuole serializzare un particolare membro allora si utilizza l'attributo [NonSerialized]. Nel caso fosse necessario eseguire del codice dopo l'operazione di deserializzazione (per esempio per impostare membri calcolati che non sono stati serializzati) si può implementare l'interfaccia IDeserializationCallback come mostrato nell'esempio.

1 [Serializable] 2 class Student : IDeserializationCallback 3 { 4 public Student(string name, string surname, DateTime birthDate) 5 { 6 Name = name; 7 Surname = surname; 8 BirthDate = birthDate; 9 calculateAge(); 10 } 11 12 public string Name { get; set; } 13 public string Surname { get; set; } 14 public DateTime BirthDate { get; set; } 15 16 [NonSerialized] 17 [SoapIgnore] 18 private int age; 19 20 public int Age 21 { 22 get 23 { 24 return age; 25 } 26 set 27 { 28 age = value; 29 } 30 } 31 32 public override string ToString() 33 { 34 return Name + ", " + Surname + ", " + BirthDate.ToShortDateString() + ", " + age; 35 } 36 37 private void calculateAge() 38 { 39 Age = DateTime.Now.Year - BirthDate.Year; 40 } 41 42 public void OnDeserialization(object sender) 43 { 44 calculateAge(); 45 } 46 }


Con la classe BinaryFormatter è possibile serializzare in modo efficiente l'oggetto ma questo sarà accessibile solo da parte di altre applicazioni .NET:

static void Main(string[] args) { Student student = new Student("Andrea", "Angella", new DateTime(1984, 7, 14)); // Binary Serialization using (FileStream fs = new FileStream("file.dat", FileMode.Create)) { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(fs, student); } // Binary Deserialization using (FileStream fs = new FileStream("file.dat", FileMode.Open)) { BinaryFormatter bf = new BinaryFormatter(); student = (Student)bf.Deserialize(fs); } Console.Write(student); Console.ReadKey(); }

 

La classe SoapFormatter (assembly System.Runtime.Serialization.Formatters.Soap) permette di serializzare un oggetto come un SOAP Envelop adatto per essere condiviso anche con applicazioni non appartenenti al mondo .NET. Il suo utilizzo è analogo a quello della classe BinaryFormatter. E' possibile controllare la formattazione utilizzando opportuni attributi come [SoapAttribute], [SoapElement], [SoapEnum], [SoapIgnore] e [SoapInclude].

E' possibile serializzare un oggetto in uno specifico formato XML attraverso la classe XmlSerializer. Questa modalità ovviamente porta con se i vantaggi del linguaggio XML e cioè forte interoperabilità, amministrazione user-friendly e migliore compatibilità all'indietro. La serializzazione XML può serializzare solamente membri pubblici (al contrario di quella binaria) e non possono essere serializzati grafi di oggetti. E' richiesto un costruttore di default. Anche in questo caso è possibile personalizzare il markup xml che sarà generato utilizzando opportuni attributi come [XmlAttribute], [XmlElement], [XmlIgnore], [XmlEnum] ecc.

E' interessante la possibiiltà di generare classi con attributi xml a partire da un file XML Schema Definition. Lo strumento da utilizzare è il tool a linea di comando xsd.

Se si vuole avere un controllo maggiore sul processo di serializzazione e deserializzazione è possibile implementare l'interfaccia ISerializable. Tramite il metodo GetObjectData si specificano i membri che si vogliono serializzare. All'interno di un particolare costruttore (chiamato dopo la fase di deserializzazione) sarà possibile accedere a questi valori e ripristinare il contenuto dell'oggetto. E' possibile intervenire prima e dopo la fase di serializzazione e deserializzazione inserendo opportuni metodi decorati con gli attributi [OnSerializing], [OnSerialized], [OnDeserializing], [OnDeserialized]. La classe StreamingContext è utile se si vuole serializzare un oggetto in modo differente in base alla destinazione (stesso processo, processi su macchine differenti, ecc. ).

[Serializable] public class Student : ISerializable { public string Name { get; set; } public string Surname { get; set; } public DateTime BirthDate { get; set; } public int Age { get; set; } // Costruttore standard public Student(string name, string surname, DateTime birthDate) { Name = name; Surname = surname; BirthDate = birthDate; calculateAge(); } // Costruttore per la deserializzazione public Student(SerializationInfo info, StreamingContext context) { Name = info.GetString("Name"); Surname = info.GetString("Surname"); BirthDate = info.GetDateTime("BirthDate"); } [OnSerializing] void BeforeSerialization(StreamingContext context) { // ... } [OnSerialized] void AfterSerialization(StreamingContext context) { // ... } [OnDeserializing] void BeforeDeserialization(StreamingContext context) { // ... } [OnDeserialized] void AfterDeserialization(StreamingContext context) { calculateAge(); } public override string ToString() { return Name + ", " + Surname + ", " + BirthDate.ToShortDateString() + ", " + Age; } private void calculateAge() { Age = DateTime.Now.Year - BirthDate.Year; } #region ISerializable Members // Metodo chiamato durante la fase di serializzazione public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("Name", Name); info.AddValue("Surname", Surname); info.AddValue("BirthDate", BirthDate); } #endregion }


Anche se è raramente necessario è bene sapere che è offerta anche la possibilità di realizzare dei formatter personalizzati. Invece di utilizzare ad esempio la classe BinaryFormatter è possibile costruire il proprio formatter implementando l'interfaccia IFormatter o IGenericFormatter

posted @ sabato 1 novembre 2008 23.59 | Feedback (2) | Filed Under [ Exam 70-536 Application Development Foundation ]

venerdì 24 ottobre 2008

Piattaforma di Social Bookmarking per Technet e MSDN

Voglio annunciare la nascita della piattaforma italiana di Social Bookmarking per sviluppatori e professionisti IT. L'idea sarà quella di integrarla in una serie di servizi che andranno sotto il nome di "Microsoft Social Platform".

Fonte della notizia: http://blogs.technet.com/italy/archive/2008/10/23/social-bookmarking-ma-non-solo.aspx

Ecco i rispettivi link:

Interessante la presenza di un Plug-in per Windows Live Writer che permette di aggiungere ai propri post i link che permettono ai lettori di condividere il post su diversi servizi di social bookmarking.

Di seguito ecco un esempio di contenuto generato da questo plug-in:

Condividi questo post :