Serializzazione e archiviazione di documenti

Microsoft .NET Framework offre un ambiente potente per la creazione e la visualizzazione di documenti di alta qualità. Funzionalità avanzate che supportano documenti fissi e documenti di flusso, controlli di visualizzazione avanzati, combinati con potenti funzionalità grafiche 2D e 3D portano le applicazioni .NET Framework a un nuovo livello di qualità e esperienza utente. La possibilità di gestire in modo flessibile una rappresentazione in memoria di un documento è una funzionalità chiave di .NET Framework e la possibilità di salvare e caricare in modo efficiente i documenti da un archivio dati è una necessità di quasi ogni applicazione. Il processo di conversione di un documento da una rappresentazione in memoria interna a un archivio dati esterno è detto serializzazione. Il processo inverso di lettura di un archivio dati e di creazione dell'istanza in memoria originale è detto deserializzazione.

Informazioni sulla serializzazione di documenti

In teoria, il processo di serializzazione e deserializzazione di un documento in memoria è trasparente per l'applicazione. L'applicazione chiama un metodo di scrittura del serializzatore per salvare il documento, mentre un metodo di lettura del deserializzatore accede all'archivio dati e ricrea l'istanza originale in memoria. Il formato specifico in cui vengono archiviati i dati non costituisce in genere un problema per l'applicazione, purché il processo di serializzazione e deserializzazione ricrei il documento nel formato originale.

Nelle applicazioni sono spesso disponibili varie opzioni di serializzazione che consentono all'utente di salvare i documenti in supporti o formati diversi. Ad esempio, è possibile che in un'applicazione siano disponibili opzioni "Salva con nome" per l'archiviazione di un documento su disco, in un database o come servizio Web. Allo stesso modo, serializzatori diversi potrebbero archiviare il documento in formati diversi quali HTML, RTF, XML, XPS o, in alternativa, in un formato di terze parti. Per l'applicazione, la serializzazione definisce un'interfaccia che isola i dettagli del supporto di archiviazione nell'implementazione di ogni specifico serializzatore. Oltre ai vantaggi dell'incapsulamento dei dettagli dell'archiviazione, le API di .NET Framework System.Windows.Documents.Serialization offrono diverse altre funzionalità importanti.

Funzionalità dei serializzatori di documenti di .NET Framework 3.0

  • L'accesso diretto agli oggetti documento di alto livello (albero logico e oggetti visivi) consente di archiviare in modo efficiente contenuto impaginato, elementi 2D/3D, immagini, supporti, collegamenti ipertestuali, annotazioni e altro contenuto di supporto.

  • Operazioni sincrone e asincrone.

  • Supporto per serializzatori plug-in con funzionalità avanzate:

    • Accesso a livello di sistema per l'uso da parte di tutte le applicazioni .NET Framework.

    • Individuazione semplice dei plug-in dell'applicazione.

    • Facilità di distribuzione, installazione e aggiornamento per i plug-in di terze parti personalizzati.

    • Supporto dell'interfaccia utente per impostazioni e opzioni di runtime personalizzate.

Percorso di stampa XPS

Il percorso di stampa XPS di Microsoft .NET Framework offre anche un meccanismo estendibile per la scrittura di documenti tramite output di stampa. XPS funge sia da formato di file di documento che dal formato nativo dello spooling di stampa per Windows Vista. I documenti XPS possono essere inviati direttamente alle stampanti compatibili con XPS senza la necessità di eseguire la conversione in un formato intermedio. Vedere Cenni preliminari sulla stampa per altre informazioni sulle opzioni e le funzionalità dell'output del percorso di stampa.

Serializzatori plug-in

Le System.Windows.Documents.Serialization API forniscono il supporto sia per i serializzatori plug-in che per i serializzatori collegati installati separatamente dall'applicazione, per l'associazione in fase di esecuzione e per l'accesso tramite il SerializerProvider meccanismo di individuazione. I serializzatori plug-in offrono notevoli vantaggi in termini di facilità di distribuzione e uso a livello di sistema. I serializzatori collegati possono essere implementati anche per ambienti con attendibilità parziale, ad esempio applicazioni browser XAML (XBAP) in cui i serializzatori plug-in non sono accessibili. I serializzatori collegati, basati su un'implementazione derivata della SerializerWriter classe, vengono compilati e collegati direttamente nell'applicazione. Sia i serializzatori plug-in che i serializzatori collegati funzionano tramite eventi e metodi pubblici identici che semplificano l'uso di uno o di entrambi i tipi di serializzatori nella stessa applicazione.

I serializzatori plug-in garantiscono agli sviluppatori di applicazioni estensibilità per nuovi progetti di archiviazione e formati di file, senza la necessità di scrivere direttamente codice per ogni potenziale formato in fase di compilazione. I serializzatori plug-in sono utili anche agli sviluppatori di terze parti in quanto forniscono un metodo standardizzato per distribuire, installare e aggiornare plug-in accessibili al sistema per formati di file personalizzati o proprietari.

Uso di un serializzatore plug-in

I serializzatori plug-in sono semplici da usare. La SerializerProvider classe enumera un SerializerDescriptor oggetto per ogni plug-in installato nel sistema. La IsLoadable proprietà filtra i plug-in installati in base alla configurazione corrente e verifica che il serializzatore possa essere caricato e usato dall'applicazione. Fornisce SerializerDescriptor anche altre proprietà, ad esempio DisplayName e DefaultFileExtension, che l'applicazione può usare per richiedere all'utente di selezionare un serializzatore per un formato di output disponibile. Un serializzatore di plug-in predefinito per XPS viene fornito con .NET Framework ed è sempre enumerato. Dopo aver selezionato un formato di output, il CreateSerializerWriter metodo viene usato per creare un SerializerWriter oggetto per il formato specifico. Il SerializerWriter.Write metodo può quindi essere chiamato per restituire il flusso di documenti nell'archivio dati.

Nell'esempio seguente viene illustrata un'applicazione che usa il SerializerProvider metodo in una proprietà "PlugInFileFilter". PlugInFileFilter enumera i plug-in installati e compila una stringa di filtro con le opzioni di file disponibili per un oggetto SaveFileDialog.

// ------------------------ PlugInFileFilter --------------------------
/// <summary>
///   Gets a filter string for installed plug-in serializers.</summary>
/// <remark>
///   PlugInFileFilter is used to set the SaveFileDialog or
///   OpenFileDialog "Filter" property when saving or opening files
///   using plug-in serializers.</remark>
private string PlugInFileFilter
{
    get
    {   // Create a SerializerProvider for accessing plug-in serializers.
        SerializerProvider serializerProvider = new SerializerProvider();
        string filter = "";

        // For each loadable serializer, add its display
        // name and extension to the filter string.
        foreach (SerializerDescriptor serializerDescriptor in
            serializerProvider.InstalledSerializers)
        {
            if (serializerDescriptor.IsLoadable)
            {
                // After the first, separate entries with a "|".
                if (filter.Length > 0)   filter += "|";

                // Add an entry with the plug-in name and extension.
                filter += serializerDescriptor.DisplayName + " (*" +
                    serializerDescriptor.DefaultFileExtension + ")|*" +
                    serializerDescriptor.DefaultFileExtension;
            }
        }

        // Return the filter string of installed plug-in serializers.
        return filter;
    }
}

Dopo che un nome di file di output è stato selezionato dall'utente, nell'esempio seguente viene illustrato l'uso del CreateSerializerWriter metodo per archiviare un determinato documento in un formato specificato.

// Create a SerializerProvider for accessing plug-in serializers.
SerializerProvider serializerProvider = new SerializerProvider();

// Locate the serializer that matches the fileName extension.
SerializerDescriptor selectedPlugIn = null;
foreach ( SerializerDescriptor serializerDescriptor in
                serializerProvider.InstalledSerializers )
{
    if ( serializerDescriptor.IsLoadable &&
         fileName.EndsWith(serializerDescriptor.DefaultFileExtension) )
    {   // The plug-in serializer and fileName extensions match.
        selectedPlugIn = serializerDescriptor;
        break; // foreach
    }
}

// If a match for a plug-in serializer was found,
// use it to output and store the document.
if (selectedPlugIn != null)
{
    Stream package = File.Create(fileName);
    SerializerWriter serializerWriter =
        serializerProvider.CreateSerializerWriter(selectedPlugIn,
                                                  package);
    IDocumentPaginatorSource idoc =
        flowDocument as IDocumentPaginatorSource;
    serializerWriter.Write(idoc.DocumentPaginator, null);
    package.Close();
    return true;
}

Installazione di serializzatori plug-in

La SerializerProvider classe fornisce l'interfaccia dell'applicazione di livello superiore per l'individuazione e l'accesso del serializzatore plug-in. SerializerProvider individua e fornisce all'applicazione un elenco dei serializzatori installati e accessibili nel sistema. Le specifiche dei serializzatori installati vengono definite tramite le impostazioni del Registro di sistema. I serializzatori plug-in possono essere aggiunti al Registro di sistema usando il RegisterSerializer metodo oppure se .NET Framework non è ancora installato, lo script di installazione del plug-in può impostare direttamente i valori del Registro di sistema. Il UnregisterSerializer metodo può essere usato per rimuovere un plug-in installato in precedenza oppure le impostazioni del Registro di sistema possono essere reimpostate in modo analogo da uno script di disinstallazione.

Creazione di un serializzatore plug-in

Sia i serializzatori plug-in che i serializzatori collegati usano gli stessi eventi e metodi pubblici esposti e possono essere progettati in modo simile per funzionare in modalità sincrona o asincrona. Per creare un serializzatore plug-in, sono in genere necessari tre passaggi di base:

  1. Implementare ed eseguire il debug del serializzatore innanzitutto come serializzatore collegato. La creazione iniziale di un serializzatore compilato e collegato direttamente in un'applicazione di prova consente l'accesso completo ai punti di interruzione e ad altri servizi di debug utili per il test.

  2. Dopo aver testato completamente il serializzatore, viene aggiunta un'interfaccia ISerializerFactory per creare un plug-in. L'interfaccia ISerializerFactory consente l'accesso completo a tutti gli oggetti .NET Framework che includono l'albero logico, UIElement gli oggetti, IDocumentPaginatorSourcegli elementi e Visual . Fornisce inoltre ISerializerFactory gli stessi metodi e eventi sincroni e asincroni usati dai serializzatori collegati. Poiché l'output dei documenti di grandi dimensioni può richiedere tempo, le operazioni asincrone sono consigliate per garantire l'interazione dell'utente e fornire un'opzione "Annulla" se si verifica un problema relativo all'archivio dati.

  3. Dopo la creazione del serializzatore plug-in, viene implementato uno script di installazione per la distribuzione, l'installazione e la disinstallazione del plug-in (vedere la sezione precedente "Installazione di serializzatori plug-in").

Vedi anche