Udostępnij za pośrednictwem


Przegląd serializacji projektanta

Projektant serializacji możesz utrzymują stan składników w czasie projektowania lub czas trwania.

Serializacji dla obiektów

.NET Framework Obsługuje kilka typów serializacji, takich jak generowania kodu, serializacji protokołu SOAP, serializacji binarnej i serializacji XML.

Projektant serializacji jest specjalną formę serializacji, która obejmuje rodzaj obiektu trwałość zazwyczaj związanego z narzędzi programistycznych.Projektant serializacji to proces konwersji wykresu obiektu pliku źródłowego, które później mogą być używane do odzyskania wykres obiektu.Plik źródłowy może zawierać kod, znaczników lub nawet informacje tabeli SQL.Projektant serializacji działa dla wszystkich obiektów środowiska wykonawczego języka wspólnego.

Projektant serializacji różni się od serializacji obiektu typowe na kilka sposobów:

  • Obiekt wykonywania serializacji jest niezależna od obiektu run-time, dzięki czemu logikę w czasie projektowania, można usunąć ze składnika.

  • Schematu serializacji została opracowana przy założeniu, że obiekt będzie utworzony w stanie w pełni zainicjowany i następnie zmodyfikowane za pomocą właściwości i metody wywołania podczas deserialization.

  • Właściwości obiektu, które mają wartości, które nigdy nie zostały ustawione na obiekcie nie są szeregowane.Odwrotnie deserializacji strumienia nie może zainicjować wszystkie wartości właściwości.Bardziej szczegółowy opis zasady serializacji można uzyskać w sekcji "Ogólne zasady serializacji" w dalszej części tego tematu.

  • Nacisk jest położony na jakość zawartości w strumieniu serializacji zamiast pełnego serializacji obiektu.Jeśli żaden sposób zdefiniowane serializować obiektu tego obiektu będą przekazywane za pośrednictwem zamiast wzbudzania wyjątku.Projektant serializacji ma sposobów serializować obiektu w formie prosty, czytelny dla człowieka, a nie jako obiekt nieprzezroczysty blob.

  • Strumień serializacji może mieć więcej danych niż jest to wymagane do deserializacji.Na przykład źródła kodu serializacji ma kod użytkownika zmieszane z kodu, potrzebne do deserializacji wykresu obiektu.Ten kod użytkownika musi być zachowane na serializacji i przekazywane za pośrednictwem deserializacji.

[!UWAGA]

Projektant serializacji mogą być używane w czasie wykonywania, jak również w czasie projektowania.

W poniższej tabeli przedstawiono założenia projektu spełnione z .NET Framework infrastruktury projektanta serializacji.

Celem projektu

Opis

Modułowa

Proces serializacji mogą objąć również nowe typy danych, a te typy danych umożliwiają opisy użyteczna, czytelny dla człowieka, same w sobie.

Łatwo rozszerzalny

Proces serializacji może zostać rozszerzona na pokrycie łatwo nowe typy danych.

Format neutralne

Obiekty mogą uczestniczyć w wielu różnych formatach, a projektant serializacji nie jest związana z formatem szczególnych danych.

Architektura

Architektura projektanta serializacji opiera się na metadanych, serializers i menedżera serializacji.W poniższej tabeli opisano roli każdego aspektu architektury.

Aspekt

Opis

Atrybuty metadanych

Atrybut jest używany do tworzenia powiązań typu t z niektórych serializatora S.Architektura obsługuje także atrybut "bootstrapping", używany do obiektu, który może zapewnić serializers dla typów, które nie mają ich instalowania.

Serializers

Serializator jest obiekt, który można szeregować określonego typu lub zakresu typów.Jest klasą bazową dla wszystkich formatów danych.Na przykład, może być DemoXmlSerializer base klasy, który można przekonwertować obiektu XML.Architektura jest niezależne od dowolnego formatu serializacji szczególnych i obejmuje również implementacja tej architektury oparty na kodzie Document Object Model (CodeDOM).

Menedżera serializacji

Menedżera serializacji jest obiekt, który zapewnia magazynu informacji dla wszystkich różnych serializers, które są używane do serializacji wykresu obiektu.Wykres 50 obiekty mogą mieć 50 różnych serializers, że wszystkie generować własne dane wyjściowe.Menedżera serializacji jest używany przez te serializers do komunikowania się ze sobą.

Poniższej ilustracji i procedury pokazują, jak można szeregować obiektów na wykresie, w tym przypadku a i B.

Wykres serializacji obiektu

Serializacja obiektów na wykresie

  1. Obiekt wywołujący żąda serializator dla obiektu, A od tego menedżera serializacji:

    MySerializer s = manager.GetSerializer(a);
    
  2. Atrybut metadanych a typu wiąże a serializatora żądanego typu.Obiekt wywołujący zwraca następnie serializatora serializować A:

    Blob b = s.Serialize(manager, a);
    
  3. Serializator obiektu a szereguje A.Dla każdego obiektu napotkane podczas serializowania a żąda od tego menedżera serializacji dodatkowe serializers:

    MySerializer s2 = manager.GetSerializer(b);
    Blob b2 = s2.Serialize(manager, b);
    
  4. Wynik serializacji jest zwracany do obiektu wywołującego:

    Blob b = ...
    

Zasady serializacji ogólne

Składnik zazwyczaj opisuje liczbę właściwości.Na przykład, Windows Forms Button formant ma właściwości, takich jak BackColor, ForeColor, i BackgroundImage.Po umieszczeniu Button formantu na formularzu w projektancie i przejrzeć wygenerowany kod, znajdziesz tylko podzbiór właściwości jest trwała w kodzie.Zazwyczaj są to właściwości, dla których jawnie ustawić wartości.

CodeDomSerializer Związane z Button kontroli określa zachowanie serializacji.Na poniższej liście opisano niektóre reguły używane przez CodeDomSerializer do serializacji wartości właściwości:

  • Jeśli właściwość ma DesignerSerializationVisibilityAttribute dołączony do niego, serializator to jest używane do określenia, jeśli właściwość jest seryjny (takich jak Visible lub Hidden) i jak serializować (Content).

  • Visible Lub Hidden określić wartości, jeśli właściwość jest seryjny.Content Wartość określa, w jaki sposób właściwość jest seryjny.

  • Dla właściwości o nazwie DemoProperty, jeśli składnik implementuje metodę o nazwie ShouldSerializeDemoProperty, środowiska projektowego sprawia, że późnym wiązaniem wywołanie tej metody do ustalenia, czy serializować.Na przykład, dla BackColor właściwość, wywoływana jest metoda ShouldSerializeBackColor.

  • Jeśli właściwość ma DefaultValueAttribute określony, wartość domyślna jest porównywana z bieżącą wartość na składniku.Właściwość jest seryjny, tylko wtedy, gdy bieżącą wartość niż domyślna.

  • Projektant skojarzone z danym składnikiem można również odgrywają ważną rolę w podejmowaniu decyzji serializacji przez przesłanianie właściwości lub wdrażając ShouldSerialize metody sam.

[!UWAGA]

Serializator podporządkowuje decyzji serializacji PropertyDescriptor związane z własnością i PropertyDescriptor używa zasady wymienione wcześniej.

Jeśli chcesz serializować składnika w inny sposób, można napisać własne klasy serializatora, który wynika z CodeDomSerializer i skojarzyć ją z sieci przy użyciu składnika DesignerSerializerAttribute.

Inteligentne serializatora wykonania

Jednym z wymagań projektu serializator jest, że gdy potrzebna jest nowy format serializacji, wszystkie typy danych muszą zostać zaktualizowane atrybut metadanych do obsługi tego formatu.Jednak w o serializacji dostawców, w połączeniu z serializers, używające metadane obiektu ogólnego, wymóg ten może być spełniony.W tej sekcji opisano preferowanym sposobem projektowania serializator dla określonego formatu, tak, aby potrzeba wielu serializers niestandardowego jest zminimalizowany.

Następujący schemat definiuje hipotetyczny format XML zostaną utrwalone wykresu obiektu.

<TypeName>
    <PropertyName>
        ValueString
    </PropertyName>
</TypeName>

Ten format jest seryjny, przy użyciu wymyśloną klasy o nazwie DemoXmlSerializer.

public abstract class DemoXmlSerializer 
{
    public abstract string Serialize(
        IDesignerSerializationManager m, 
        object graph);
}

Jest ważne, aby zrozumieć, że DemoXmlSerializer jest klasa modułowa buduje ciąg kawałków.Na przykład DemoXmlSerializer do Int32 typ danych zwróci ciąg "23" przekazany całkowitą wartość 23.

Serializacja dostawców

W poprzednim przykładzie schematu wynika, że istnieją dwa podstawowe typy do obsługi:

  • Obiekty, które mają właściwości podrzędne.

  • Obiekty, które mogą być konwertowane na tekst.

Byłoby trudno znajdują się na każdej klasy z serializatora niestandardowego, który może konwertować tej klasy do tekstu lub znaczników XML.Serializacja dostawców rozwiązać ten udostępniając mechanizm wywołania zwrotnego, w którym obiekt jest biorąc pod uwagę możliwość udzielenia serializatora dla danego typu.W tym przykładzie zestaw dostępnych typów jest ograniczony przez następujące warunki:

  • Jeśli typ można przekonwertować na ciąg znaków za pomocą IConvertible interfejsu, StringXmlSerializer będą używane.

  • Jeśli nie można przekonwertować typu ciąg znaków, ale jest publiczny i ma pustego konstruktora, ObjectXmlSerializer będą używane.

  • Jeżeli żadna z nich nie jest spełniony, dostawca serializacji zwróci null, wskazująca, że jest nie serializator dla obiektu.

Poniższy przykład kodu pokazuje, jak występuje rozwiązuje serializatora wywołującego, co się dzieje z tym błędem.

internal class XmlSerializationProvider : IDesignerSerializationProvider 
{
    object GetSerializer(
        IDesignerSerializationManager manager, 
        object currentSerializer, 
        Type objectType, 
        Type serializerType) 
    {

        // Null values will be given a null type by this serializer.
        // This test handles this case.
        if (objectType == null) 
        {
            return StringXmlSerializer.Instance;
        }

        if (typeof(IConvertible).IsSubclassOf(objectType)) 
        {
            return StringXmlSerializer.Instance;
        }

        if (objectType.GetConstructor(new object[]) != null) 
        {
            return ObjectXmlSerializer.Instance;
        }

        return null;
    }
}

Po dostawcy serializacji jest zdefiniowana, muszą być wprowadzane Aby użyć.Może być udzielona menedżera serializacji dostawcy serializacji poprzez AddSerializationProvider metody, ale wymaga się, że to wywołanie, należy dokonać tego menedżera serializacji.Dostawca serializacji mogą być automatycznie dodawane do menedżera serializacji przez dodanie DefaultSerializationProviderAttribute do serializatora.Atrybut ten wymaga, że dostawca serializacji ma konstruktora publicznego, puste.Poniższy przykład kodu pokazuje niezbędne zmiany do DemoXmlSerializer.

[DefaultSerializationProvider(typeof(XmlSerializationProvider))]
public abstract class DemoXmlSerializer 
{
}

Teraz, gdy zadawane menedżera serializacji dla dowolnego typu DemoXmlSerializer, domyślnego dostawcę serializacji zostaną dodane do tego menedżera serializacji, jeśli nie ma już miejsce.

Serializers

Próbki DemoXmlSerializer klasa ma dwie klasy konkretnych serializatora o nazwie StringXmlSerializer i ObjectXmlSerializer.Poniższy przykład kodu pokazuje wykonania StringXmlSerializer.

internal class StringXmlSerializer : DemoXmlSerializer
{
    internal StringXmlSerializer Instance = new StringXmlSerializer();

    public override string Serialize(
        IDesignerSerializationManager m, 
        object graph) 
    {

        if (graph == null) return string.Empty;

        IConvertible c = graph as IConvertible;
        if (c == null) 
        {
            // Rather than throwing exceptions, add a list of errors 
            // to the serialization manager.
            m.ReportError("Object is not IConvertible");
            return null;
        }

    return c.ToString(CultureInfo.InvariantCulture);
    }
}

ObjectXmlSerializer Realizacji jest bardziej skomplikowane, ponieważ wyliczanie publicznych właściwości obiektu.Poniższy przykład kodu pokazuje wykonania ObjectXmlSerializer.

internal class ObjectXmlSerializer : DemoXmlSerializer 
{
    internal ObjectXmlSerializer Instance = new ObjectXmlSerializer();

    public override string Serialize(
        IDesignerSerializationManager m, 
        object graph) 
    {

        StringBuilder xml = new StringBuilder();
        xml.Append("<");
        xml.Append(graph.GetType().FullName);
        xml.Append(">");

        // Now, walk all the properties of the object.
        PropertyDescriptorCollection properties;
        Property p;

        properties = TypeDescriptor.GetProperties(graph);

        foreach(p in properties) 
        {
            if (!p.ShouldSerializeValue(graph)) 
            {
                continue;
            }

            object value = p.GetValue(graph);
            Type valueType = null;
            if (value != null) valueType = value.GetType();

            // Get the serializer for this property
            DemoXmlSerializer s = m.GetSerializer(
                valueType, 
                typeof(DemoXmlSerializer)) as DemoXmlSerializer;

            if (s == null) 
            {
                // Because there is no serializer, 
                // this property must be passed over.  
                // Tell the serialization manager
                // of the error.
                m.ReportError(string.Format(
                    "Property {0} does not support XML serialization",
                    p.Name));
                continue;
            }

            // You have a valid property to write.
            xml.Append("<");
            xml.Append(p.Name);
            xml.Append(">");

            xml.Append(s.Serialize(m, value);

            xml.Append("</");
            xml.Append(p.Name);
            xml.Append(">");
        }

        xml.Append("</");
        xml.Append(graph.GetType().FullName);
        xml.Append(">");
        return xml.ToString();
    }
}

ObjectXmlSerializerwywołuje inne serializers dla każdej wartości właściwości.Ma dwie zalety.Po pierwsze, pozwala ObjectXmlSerializer być bardzo proste.Po drugie stanowi punkt rozszerzeń dla typów firm.Jeśli ObjectXmlSerializer jest przedstawiane z typu, które nie mogą być zapisywane przez jedną z tych serializers tego typu może być dostarczany serializatora niestandardowego.

Sposób użycia

Aby użyć tych nowych serializers, wystąpienie IDesignerSerializationManager musi zostać utworzony.Z tego wystąpienia poproś o serializatora, a następnie zapytaj serializatora serializować obiektów.W poniższym przykładzie kodu Rectangle będą używane dla obiektu do serializacji, ponieważ tego typu ma pustego konstruktora i ma cztery właściwości, które obsługują IConvertible.Zamiast stosowania IDesignerSerializationManager samodzielnie, można użyć implementacji, świadczone przez DesignerSerializationManager.

Rectangle r = new Rectangle(5, 10, 15, 20);
DesignerSerializationManager m = new DesignerSerializationManager();
DemoXmlSerializer x = (DemoXmlSerializer)m.GetSerializer(
    r.GetType(), typeof(DemoXmlSerializer);

string xml = x.Serialize(m, r);

Spowodowałoby to utworzenie następującego kodu XML.

<System.Drawing.Rectangle>
<X>
5
</X>
<Y>
10
</Y>
<Width>
15
</Width>
<Height>
15
</Height>
</System.Drawing.Rectangle>

[!UWAGA]

Kod XML nie jest wcięty.Można to łatwo osiągnąć poprzez Context właściwość IDesignerSerializationManager.Każdy poziom serializatora można dodać obiektów do stosu kontekstu, który zawiera bieżący poziom wcięcia i każdego serializatora może wyszukiwania dla tego obiektu w stosie i używany do dostarczania wcięcie.

Zobacz też

Informacje

IDesignerSerializationManager

DesignerSerializationManager

DefaultSerializationProviderAttribute

IConvertible

CodeDomSerializerBase

Inne zasoby

Rozszerzona pomoc techniczna czasu projektowania