Programowanie zaawansowane

Содержание

Слайд 2

Wprowadzenie (1)

W przestrzeni nazw System.IO znajduje się wiele typów związanych z odczytywaniem

Wprowadzenie (1) W przestrzeni nazw System.IO znajduje się wiele typów związanych z
i zapisywaniem danych.
Mogą one być wykorzystane do utrwalania danych we wskazanej lokalizacji i formacie.
Podczas tego wykładu omówiony zostanie pokrewny temat, a mianowicie serializacja obiektów.
Pozwala ona na zapisywanie i odczytanie stanu danego obiektu do/z dowolnego strumienia (typu dziedziczącego po System.IO.Stream).

Слайд 3

Wprowadzenie (2)

Możliwość serializacji obiektu jest kluczowa w przypadku potrzeby skopiowania obiektu na

Wprowadzenie (2) Możliwość serializacji obiektu jest kluczowa w przypadku potrzeby skopiowania obiektu
zdalną maszynę za pomocą różnego rodzaju technologii zdalnego dostępu, takich jak:
Warstwa zdalnego dostępu .NET (ang. remoting layer),
XML-owe usługi sieciowe,
Windows Communication Foundation.
Seirailzacja może również znaleźć zastosowanie w innych rodzajach aplikacji.
Poznamy mechanizm jej działania, różne metody serializacji oraz sposoby jej konfigurowania.

Слайд 4

Serializacja obiektów

Serializacja obiektów

Слайд 5

Serializacja

Termin serializacja oznacza proces zapisywania (i ewentualnie transformacji) stanu obiektu w postaci

Serializacja Termin serializacja oznacza proces zapisywania (i ewentualnie transformacji) stanu obiektu w
serii bajtów do strumienia (strumienia do pliku, strumienia do pamięci, itd.).
Sekwencja zapisanych danych zawiera wszystkie informacje niezbędne do rekonstrukcji (deserializacji) danego stanu obiektu.
Przy pomocy tej technologii, bardzo prostym staje się zapisanie bardzo dużej ilości danych (w różnych formatach) przy minimalnym zaangażowaniu programisty (mniejszym niż w przypadku używania typów w przestrzeni System.IO).

Слайд 6

Przykład zastosowania serializacji (1)

Dla przykładu załóżmy, że stworzyliśmy desktopową aplikację i chcemy

Przykład zastosowania serializacji (1) Dla przykładu załóżmy, że stworzyliśmy desktopową aplikację i
zapewnić sposób pozwalający na zapisywanie preferencji każdego z jej użytkowników (kolor okna, rozmiar czcionki, itd.).
W tym celu możemy zdefiniować odpowiednią klasę (np., UserPrefs), która będzie hermetyzować około 20 właściwości.
Gdybyśmy chcieli skorzystać z typu System.IO.BinaryWriter, musielibyśmy ręcznie zapisać każde pole danych z obiektu typu UserPrefs.
To samo dotyczy wczytania tych danych za pomocą typu System.IO.BinaryReader.

Слайд 7

Przykład zastosowania serializacji (2)

To oczywiście jest do zrobienia, ale używając mechanizmu serializacji

Przykład zastosowania serializacji (2) To oczywiście jest do zrobienia, ale używając mechanizmu
możemy zaoszczędzić sobie wiele pracy.
Wystarczy naszą klasę oznaczyć atrybutem [Serializable].
Dzięki temu drobnemu zabiegowi, cały stan obiektu może być utrwalony w kilku liniach kodu (co pokazuje następny slajd).

Слайд 8

Przykład zastosowania serializacji (3)

Przykład zastosowania serializacji (3)

Слайд 9

Wewnętrzne mechanizmy

Podczas gdy sam proces wykorzystania serializacji jest bardzo prosty, mechanizmy, który

Wewnętrzne mechanizmy Podczas gdy sam proces wykorzystania serializacji jest bardzo prosty, mechanizmy,
za nią odpowiadają od strony implementacji są dużo bardziej złożone.
Na przykład, podczas utrwalenia obiektu do strumienia, wszystkie powiązane z nim dane (klasy bazowe, zagregowane obiekty, itd. ) są również automatycznie serializowane.
Dlatego też , w przypadku utrwalania obiektu klasy potomnej, wszystkie dane w łańcuchu dziedziczenia też są utrwalane.
Zbiór powiązanych ze sobą obiektów reprezentowany jest za pomocą grafów obiektów.

Слайд 10

Rożne formaty serializacji

Usługi serializujące platformy .NET pozwalają na utrwalanie grafu obiektu w

Rożne formaty serializacji Usługi serializujące platformy .NET pozwalają na utrwalanie grafu obiektu
kilku różnych formatach.
Przykładowy kod przedstawiony wcześniej pokazywał użycie typu BinaryFormater, który powoduje utrwalanie stanu obiektu w spakowanym binarnym formacie.
Możemy również utrwalić graf obiektów w formacie koperty SOAP lub dokumentu XML za pomocą dwóch innych typów serializerów.
Formaty te są pomocne, gdy chcemy zapewnić łatwe przenoszenie naszego obiektu między różnymi systemami operacyjnymi, językami i architekturami.

Слайд 11

Różne strumienie

Należy pamiętać, że graf obiektów możemy zapisywać do dowolnego strumienia (obiektu klasy

Różne strumienie Należy pamiętać, że graf obiektów możemy zapisywać do dowolnego strumienia
dziedziczącej po System.IO.Stream).
W przedstawionym przykładzie utrwaliliśmy stan obiektu w lokalnym pliku.
Moglibyśmy równie dobrze zapisać go w określonym obszarze pamięci (za pomocą typu MemoryStream) lub w strumieniu sieciowym.
To co się liczy, to fakt, że pewna sekwencja bajtów poprawnie reprezentuje stan obiektów w grafie.

Слайд 12

Rola grafu obiektów

Podczas serializacji obiektu, CLR uwzględnia również wszystkie powiązane obiekty w

Rola grafu obiektów Podczas serializacji obiektu, CLR uwzględnia również wszystkie powiązane obiekty
celu zapewnienia prawidłowego utrwalenia danych.
Taki zbiór powiązanych ze sobą obiektów nazywa się grafem obiektów.
Graf obiektów stanowi prosty sposób udokumentowania powiązań między obiektami niekoniecznie odwzorowując tradycyjne relacje z programowania obiektowego („is-a”, „has-a”). Jednakże pozwalają na odpowiednie modelowanie potrzebne w tym podejściu.

Слайд 13

Grafy obiektów

Do każdego obiektu w grafie obiektów przypisywana jest unikalna wartość liczbowa.
Wartości

Grafy obiektów Do każdego obiektu w grafie obiektów przypisywana jest unikalna wartość
te są generowane automatycznie i nie mają żadnego znaczenia poza grafem.
Po przypisaniu unikalnych wartości (identyfikatorów), możliwe jest zapisanie w grafie zbioru zależności dla każdego z obiektów.

Слайд 14

Przykład grafu obiektów (1)

Dla przykładu załóżmy, że stworzyliśmy następujący zbiór klas:
bazową klasę

Przykład grafu obiektów (1) Dla przykładu załóżmy, że stworzyliśmy następujący zbiór klas:
Car, która posiada („has-a”) Radio,
potomna klasa, JamesBondCar, rozszerza klasę („is-a”) Car.
Graf obiektów dla takiego zbioru klas będzie wyglądał następująco:

Слайд 15

Przykład grafu obiektów (2)

Klasa JamesBosnCar posiada referencję do klasy Radio, ponieważ odziedziczyła

Przykład grafu obiektów (2) Klasa JamesBosnCar posiada referencję do klasy Radio, ponieważ
ją po klasie bazowej Car.
Oczywiście, CLR nie przechowuje grafu obiektów w postaci obrazka. Relacje udokumentowane na diagramie reprezentowane są w postaci matematycznej formuły
W momencie serializacji lub deserializacji instancji klasy JamesBondCar, graf obiektów zapewnia to, że obiekty klas Radio i Car również zostaną uwzględnione w tym procesie.

Слайд 16

Automatyczne generowanie grafu obiektów

Zaletą procesu serializacji jest to, że graf reprezentujący relacje

Automatyczne generowanie grafu obiektów Zaletą procesu serializacji jest to, że graf reprezentujący
między obiektami jest tworzony automatycznie „za kurtyną”.
Jeżeli jednak chcemy sami wziąć udział w jego tworzeniu (dokonać pewnych modyfikacji), możemy tego dokonać poprzez konfigurację procesu serializacji za pomocą odpowiednich atrybutów i interfejsów.
Typ XmlSerializer nie utrwala stanu przy pomocy grafu obiektów, jednakże typ ten również dokonuje serializacji i deserializacji powiązanych obiektów w przewidywalny sposób.

Слайд 17

Oznaczanie obiektów do serializacji

Aby dany obiekt był dostępny dla usług serializacji platformy

Oznaczanie obiektów do serializacji Aby dany obiekt był dostępny dla usług serializacji
.NET, wystarczy oznaczyć każdą z powiązanych klas (lub struktur) atrybutem [Serializable].
Jeżeli zdecydujemy, że dany typ posiada dane składowe, które nie powinny (lub nie mogą) brać udziału w serializacji, oznaczamy takie pola atrybutem [NonSerialized].
Może nam to pomóc wtedy, gdy w danym typie mamy dane, które nie musza być „zapamiętane”, np. pola o stałych wartościach, wartości losowe itd., a zależy nam na zmniejszeniu rozmiaru utrwalanych danych.

Слайд 18

Przykładowe klasy (1)

Dla przykładu stwórzmy kilka powiązanych klas.
Pole radioID zostało oznaczone atrybutem

Przykładowe klasy (1) Dla przykładu stwórzmy kilka powiązanych klas. Pole radioID zostało
[NonSerialized] i dlatego nie będzie utrwalone.

Слайд 19

Przykładowe klasy (2)

Dodajemy klasę bazową posiadająca Radio oraz klasę po niej dziedziczącą.

Przykładowe klasy (2) Dodajemy klasę bazową posiadająca Radio oraz klasę po niej dziedziczącą.

Слайд 20

Własności atrybutu [Serializable] (1)

Atrybut [Serializable] nie jest odziedziczony po klasie bazowej.
Dlatego też,

Własności atrybutu [Serializable] (1) Atrybut [Serializable] nie jest odziedziczony po klasie bazowej.
w przypadku tworzenia klasy dziedziczącej po klasie oznaczonej przez [Serializable], musimy ją również oznaczyć tym atrybutem. W przeciwnym razie nie będzie mogła zostać poddana procesowi serializacji.
Wszystkie obiekty w grafie obiektów muszą być oznaczone atrybutem [Serializable].

Слайд 21

Własności atrybutu [Serializable] (2)

Jeżeli spróbujemy serializować obiekty nie oznaczone tym atrybutem używając

Własności atrybutu [Serializable] (2) Jeżeli spróbujemy serializować obiekty nie oznaczone tym atrybutem
typów BinaryFormater i SoapFormater, zostanie zgłoszony wyjątek SerializationException.
Ponieważ typ XmlSerializer nie korzysta z grafów obiektów, teoretycznie nie jest wymagane oznaczanie utrwalanych typów atrybutem [Serializable].
Jednakże, w celu zapewnienia możliwości serializacji danego typu w dowolnym formacie, najczęściej dany typ (i typy z nim powiązane) oznacza się odpowiednim atrybutem.

Слайд 22

Pola prywatne, publiczne i właściwości (1)

Typy BinaryFormater i SoapFormater są zaprogramowane do

Pola prywatne, publiczne i właściwości (1) Typy BinaryFormater i SoapFormater są zaprogramowane
utrwalania wszystkich serializowalnych pól danych (bez względu na to, czy są nimi pola prywatne, pola publiczne lub pola prywatne widoczne poprzez publiczne właściwości).
Typ XmlSerializer serializuje wyłącznie pola publiczne i pola prywatne widoczne poprzez publiczne właściwości.
Zwykłe pola prywatne są pomijane.

Слайд 23

Pola prywatne, publiczne i właściwości (2)

Pola prywatne, publiczne i właściwości (2)

Слайд 24

Pola prywatne, publiczne i właściwości (3)

W przypadku, gdy obiekt klasy Person będziemy

Pola prywatne, publiczne i właściwości (3) W przypadku, gdy obiekt klasy Person
serializować za pomocą typów BinaryFormater i SoapFormater, zobaczymy, że pola isAlive, personAge i fName zostaną zapisane we wskazanym strumieniu.
W przypadku zastosowania typu XmlSerializer, pole personAge nie zostanie zapisane (ponieważ to prywatne pole nie jest udostępniane za pomocą publicznej właściwości typu).
Jeżeli chcemy, aby zostało ono uwzględniono musimy oznaczyć je jako publiczne lub dodać odpowiednią właściwość.

Слайд 25

Formatery serializacji

Formatery serializacji

Слайд 26

Formatery serializacji

Po skonfigurowaniu typów do możliwości ich serializoacji na platformie .NET poprzez

Formatery serializacji Po skonfigurowaniu typów do możliwości ich serializoacji na platformie .NET
oznaczenie ich niezbędnymi atrybutami, kolejnym krokiem jest wybór formatu (binarny, SOAP lub XML), w jakim powinny być utrwalone stany obiektów.
Każda z możliwości jest reprezentowana przez jedną z klas:
BinaryFormater,
SoapFormater,
XmlSerializer.

Слайд 27

Klasa BinaryFormater

Typ BinaryFormater zapisuje stan obiektu do wskazanego strumienia używając formatu binarnego.
Zdefiniowany

Klasa BinaryFormater Typ BinaryFormater zapisuje stan obiektu do wskazanego strumienia używając formatu
jest w przestrzeni nazw System.Runtime.Serialization.Formaters.Binary, która jest częścią pakietu mscorlib.dll.
Dlatego też, aby skorzystać z tego formatera wystarczy wpisać odpowiednią dyrektywę using.

Слайд 28

Klasa SoapFormater

Typ SospFormater utrwala stan obiektu jako wiadomość w formacie SOAP.
Zdefiniowany jest

Klasa SoapFormater Typ SospFormater utrwala stan obiektu jako wiadomość w formacie SOAP.
on w przestrzeni nazw System.Runtime.Serialization.Formaters.Soap.
Funkcjonalność ta znajduje się w osobnym pakiecie.
Dlatego też, aby skorzystać z tego typu należy dodać referencję do pakietu System.Runtime.Serialization.Formatters.Soap.dll, a następnie dodać do programu odpowiednią dyrektywę using.

Слайд 29

Klasa XmlSerializer

Typ SospSerializer utrwala stan obiektu w postaci dokumentu XML.
Aby użyć tego

Klasa XmlSerializer Typ SospSerializer utrwala stan obiektu w postaci dokumentu XML. Aby
typu musimy dopisać dyrektywę using z przestrzenią nazw System.Xml.Serialization i dodać referencję do pakietu System.Xml.dll.
Wszystkie projekty w Visual Studio 2015 mają automatycznie dołączoną referencję do wspomnianego pakietu. Zatem wystarczy dopisać:

Слайд 30

Wspólne interfejsy

Wszystkie wymienione formatery dziedziczą bezpośrednio po klasie System.Object. Nie dzielą zatem

Wspólne interfejsy Wszystkie wymienione formatery dziedziczą bezpośrednio po klasie System.Object. Nie dzielą
wspólnego zbioru składowych związanych z serializacją.
Jednakże, BinaryFormater i SoapFormater wspierają wspólne składowe poprzez implementację interfejsów IFormater i IRemotingFormater
XmlSerializer nie implementuje żadnego z nich.

Слайд 31

Interfejs IFormater

Interfejs System.Runtime.Serialization.IFormater definiuje podstawowe metody Serialize() i Deserialize() oraz kilka właściwości

Interfejs IFormater Interfejs System.Runtime.Serialization.IFormater definiuje podstawowe metody Serialize() i Deserialize() oraz kilka
wykorzystywanych „po cichu” przez implementujące go typy.

Слайд 32

Interfejs IRemotingFormater

Interfejs System.Runtime.Remoting.Messaging.IRemotingFormater (wykorzystywany przez warstwę zdalnego dostępu .NET) przeciąża metody Serialize()

Interfejs IRemotingFormater Interfejs System.Runtime.Remoting.Messaging.IRemotingFormater (wykorzystywany przez warstwę zdalnego dostępu .NET) przeciąża metody
i Deserialize() do postaci bardziej odpowiadającej rozproszonemu utrwalaniu.
Interfejs ten rozszerza bardziej ogólny interfejs IFormater.

Слайд 33

Przykładowe wykorzystanie interfejsu IFormater

Mimo, że raczej nie korzysta się bezpośrednio z wymienionych

Przykładowe wykorzystanie interfejsu IFormater Mimo, że raczej nie korzysta się bezpośrednio z
interfejsów, ich przykładowe zastosowanie może wynikać z bazującego na interfejsach polimorfizmu.
Instancję typy BinaryFormater i SoapFormater możemy przypisać do referencji do interfejsu IFormater.

Слайд 34

Wierność zapisywanych nazw (1)

Najbardziej oczywistą różnicą między trzema poznanymi formaterami jest sposób,

Wierność zapisywanych nazw (1) Najbardziej oczywistą różnicą między trzema poznanymi formaterami jest
w jaki graf obiektów jest utrwalany w strumieniu (binarny, SOAP lub XML).
Istnieje jeszcze kilka innych różnic między formaterami.
Podczas korzystania z typu BinaryFormater, utrwalone zostaną nie tylko pola danych, ale również pełna kwalifikowana nazwa każdego z typów i pełna nazwa definiującego je pakietu (nazwa, wersja, klucz publiczny, i lokalizacja).
Utrwalanie tych dodatkowych danych czynią typ BinaryFormater idealnym wyborem, jeżeli chcemy przenosić stan obiektu (pełną jego kopię) między maszynami pracującymi w oparciu o platformę .NET.

Слайд 35

Wierność zapisywanych nazw (2)

Typ SoapFormater utrwala informację o pakiecie w postaci XML-owych

Wierność zapisywanych nazw (2) Typ SoapFormater utrwala informację o pakiecie w postaci
przestrzeni nazw.
Na przykład, w przypadku serializacji klasy Person jako wiadomości SOAP, otrzymalibyśmy następujący wynik:

Слайд 36

Wierność zapisywanych nazw (3)

Typ XmlSerializer nie próbuje zachowywać całkowitej zgodności typów i

Wierność zapisywanych nazw (3) Typ XmlSerializer nie próbuje zachowywać całkowitej zgodności typów
dlatego nie utrwala pełnej kwalifikowanej nazwy typu ani nazwy pakietu.
Powodem tego jest otwarta natura XML-owej reprezentacji danych.

Слайд 37

Wierność zapisywanych nazw (4)

Jeżeli chcemy utrwalić stan obiektu w postaci, która może

Wierność zapisywanych nazw (4) Jeżeli chcemy utrwalić stan obiektu w postaci, która
być wykorzystana przez dowolny system operacyjny (Windows XP, Mac OS X i różne dystrybucje Linuxa), dowolną platformę (.NET, J2EE, COM, itd.) lub dowolny język programistyczny, nie musimy dołączać informacji o pełnych nazwach typów.
Nie możemy być pewni, że wszyscy potencjalni odbiorcy będą w stanie zrozumieć specyficzne dla platformy .NET typy danych.
Typy SoapFormater i XmlSerializer są idealnym wyborem, jeżeli chcemy zapewnić jak najszerszy dostęp do utrwalanych danych.

Слайд 38

Serializacja za pomocą typu BinaryFormater (1)

Dwie kluczowe metody to:
Serialize() – utrwalenie grafu

Serializacja za pomocą typu BinaryFormater (1) Dwie kluczowe metody to: Serialize() –
obiektów do wskazanego strumienia jako sekwencji bajtów,
Deserialize() – skonwertowania utrwalonej sekwencji bajtów do grafu obiektów.

Слайд 39

Serializacja za pomocą typu BinaryFormater (2)
Metoda Serialize() odpowiedzialna jest za skomponowanie grafu

Serializacja za pomocą typu BinaryFormater (2) Metoda Serialize() odpowiedzialna jest za skomponowanie
obiektów i przeniesienie sekwencji bajtów do wskazanego strumienia.

Слайд 40

Serializacja za pomocą typu BinaryFormater (3)

Wynikiem użycia typu BinaryFormater jest następujący plik

Serializacja za pomocą typu BinaryFormater (3) Wynikiem użycia typu BinaryFormater jest następujący
binarny przechowujący stan wskazanego obiektu:

Слайд 41

Serializacja za pomocą typu BinaryFormater (4)

Deserializacja stanu obiektu z pliku binarnego.
Metoda Deserialize()

Serializacja za pomocą typu BinaryFormater (4) Deserializacja stanu obiektu z pliku binarnego.
zwraca obiekty ogólnej klasy System.Obiect , dlatego musimy użyć odpowiedniego jawnego rzutowania.

Слайд 42

Serializacja za pomocą typu SoapFormater (1)

Specyfikacja SOAP (ang. Simple Object Access Protocol)

Serializacja za pomocą typu SoapFormater (1) Specyfikacja SOAP (ang. Simple Object Access
definiuje standardowy proces, w jaki mogą być wywoływane metody w sposób niezależny od platformy i systemu operacyjnego.
Programowo, serializacjia przebiega identycznie, jak w przypadku typy BinaryFormater.

Слайд 43

Serializacja za pomocą typu SoapFormater (2)

Wynikowy plik zawiera stan obiektu oraz relacje

Serializacja za pomocą typu SoapFormater (2) Wynikowy plik zawiera stan obiektu oraz
między jego poszczególnymi podobiektami (atrybut #ref).

Слайд 44

Serializacja za pomocą typu XmlSerializer (1)

Typ XmlSerializer służy do zapisania publicznego stanu

Serializacja za pomocą typu XmlSerializer (1) Typ XmlSerializer służy do zapisania publicznego
obiektu w postaci czystego XML-a.
Serializacja ta różni się tym od wcześniejszych, że możemy podać informacje o serializowanych typach.
Pierwszy argument konstruktora to informacje o typie, który jest korzeniem dokumenty.
Drugi argument to tablica z informacjami (metadanymi) o pod-elementach dokumentu (typach powiązanych z głównym).

Слайд 45

Serializacja za pomocą typu XmlSerializer (2)

Wynikiem serializacji naszego obiektu jest nastepujący dokument

Serializacja za pomocą typu XmlSerializer (2) Wynikiem serializacji naszego obiektu jest nastepujący dokument XML.
XML.

Слайд 46

Kontrola sposobu generowania dokumentu XML

XmlSerializer wymaga zdefiniowania dla każdej z klas biorącej

Kontrola sposobu generowania dokumentu XML XmlSerializer wymaga zdefiniowania dla każdej z klas
udział w serializacji domyślnego konstruktora.
Dokumenty XML powinny być zgodne ze zdefiniowanymi wcześniej schematami (XML schema, DTD).
Domyślnie, każde z pól przekształcane jest do elementu dokumentu XML.
Jeżeli chcemy zmienić sposób tworzenia dokumentu reprezentującego stan naszego obiektu (np. jedno z pól zdefiniować jako atrybut głównego elementu) możemy skorzystać ze zbioru atrybutów zdefiniowanych w przestrzeni nazw System.Xml.Serialization.

Слайд 47

Atrybuty przestrzeni System.Xml.Serialization

Atrybuty przestrzeni System.Xml.Serialization

Слайд 48

Przykładowe zastosowanie atrybutów

Wynikowy dokument XML.

Zmiana w definicji klasy (zastosowanie atrybutów)

Nowy wynikowy dokument

Przykładowe zastosowanie atrybutów Wynikowy dokument XML. Zmiana w definicji klasy (zastosowanie atrybutów) Nowy wynikowy dokument XML
XML

Слайд 49

Ponieważ kolekcje z przestrzeni nazw System.Collections i System.Collection.Generic są serializowalne (oznaczone atrybutem

Ponieważ kolekcje z przestrzeni nazw System.Collections i System.Collection.Generic są serializowalne (oznaczone atrybutem
[Serializable]), serilaizacja kolekcji nie różni się niczym od serializacji zwykłych grafów obiektów.
Przykład serializacji kolekcji za pomocą typu BinaryFormater.

Serializacja kolekcji obiektów (1)

Слайд 50

Serializacja kolekcji obiektów (2)

Serializacja za pomocą typu XmlSerializer wymaga podania metadanych o

Serializacja kolekcji obiektów (2) Serializacja za pomocą typu XmlSerializer wymaga podania metadanych
odpowiednich typach. W typ przyapdku głównym typem będzie kolekcja generyczna List.

Слайд 51

Konfiguracja procesu serializacji

Konfiguracja procesu serializacji

Слайд 52

Konfiguracja procesu serializacji

W niektórych przypadkach, domyślne działanie serializacji może okazać się niewystarczające.
Możemy

Konfiguracja procesu serializacji W niektórych przypadkach, domyślne działanie serializacji może okazać się
chcieć w pewien sposób zmodyfikować proces serializacji, np.:
Pewna reguła biznesowa mówi nam, że pola musza być utrwalone w pewnym zadanym formacie,
Możemy chcieć dodać dodatkową informację, której nie ma w polach obiektu (czas utrwalenia, unikalny identyfikator, itd.).
Przestrzeń nazw System.Runtime.Serialization dostarcza kilku typów, które pozwalają na konfigurację procesu serializacji.

Слайд 53

Typy związane z konfiguracją serializacji

Typy związane z konfiguracją serializacji

Слайд 54

Kolejne fazy procesu serializacji (1)

W momencie serializacji obiektu, typ BinaryFormater, przesyła następujące

Kolejne fazy procesu serializacji (1) W momencie serializacji obiektu, typ BinaryFormater, przesyła
informacje do danego strumienia:
pełną kwalifikowaną nazwę obiektów w grafie obiektów,
nazwę pakietu definiującego graf obiektów,
instancję klasy SerializationInfo zawierającą informację o stanach każdego z obiektów w utrwalanym grafie obiektów.
Podczas procesu deserializacji, typ BinaryFormater wykorzystuje te informacje do odtworzenia identycznej kopi obiektu (jak przed zapisem).
Typ SoapFormater zachowuje się podobnie.

Слайд 55

Kolejne fazy procesu serializacji (2)

Poza przenoszeniem danych do i ze strumienia, formatery

Kolejne fazy procesu serializacji (2) Poza przenoszeniem danych do i ze strumienia,
analizują składowe obiektów w grafie szukając następujących elementów infrastruktury:
Sprawdzane jest, czy typ danego obiektu oznaczony jest atrybutem [Serializable].
Jeżeli jest oznaczony tym atrybutem, sprawdza się, czy typ danego obiektu implementuje interfejs ISerializable. Jeżeli tak, wywoływana jest metoda GetObjectData() danego obietku.
Jeżeli dany obiekt nie implementuje tego interfejsu, uruchomiany jest domyślny proces serializujący wszystkie pola nieoznaczone atrybutem [NonSerialized].
Dodatkowo, oprócz sprawdzania implementowania interfejsu ISerializable, sprawdzane jest czy dany typ obiektu posiada metody oznaczone atrybutami [OnSerializing], [OnSerialized], [OnDeserializing], [OnDeserialized].

Слайд 56

Implementacja interfejsu ISerializable

Obiekty oznaczone atrybutem [Serializable] mogą implementować interfejs ISerializable. Pozwala to

Implementacja interfejsu ISerializable Obiekty oznaczone atrybutem [Serializable] mogą implementować interfejs ISerializable. Pozwala
na zaangażowanie się w proces serializacji i wykonywanie formatowania danych w wybranym momencie (przed lub po).
Od wersji platformy .NET 2.0, preferowane jest stosowanie metod oznaczonych odpowiednimi atrybutami.
Interfejs ISerializable definiuje jedną metodę.

Слайд 57

Klasa SerializationInfo

Metoda GetObjectData() jest wywoływana automatycznie przez formater w czasie serializacji.
Implementacja tej

Klasa SerializationInfo Metoda GetObjectData() jest wywoływana automatycznie przez formater w czasie serializacji.
metody wypełnia parametr (SerializationInfo) zbiorem par nazwa/wartość reprezentujących pola danych obiektu.
Typ SerializationInfo definiuje wiele wariantów przeładowanej metody Addvalue() oraz kilka właściwości pozwalających na pobranie i ustawienie nazwy typu, pakietu i liczby składowych.

Слайд 58

Specjalny konstruktor (1)

Klasa implementująca interfejs ISerializable musi również definiować specjalny konstruktor o

Specjalny konstruktor (1) Klasa implementująca interfejs ISerializable musi również definiować specjalny konstruktor
następujących parametrach:
Konstruktor jest deklarowany jako chroniony po to, aby nie mogli go wywoływać „zwykli” użytkownicy.
Pierwszym parametrem konstruktora jest instancja typu SerializationInfo, zawierająca zbiór parametrów odczytanych ze strumienia, które następnie zostają przypisane odpowiednim polom danych odtwarzanego obiektu.

Слайд 59

Specjalny konstruktor (2)

Drugim parametrem tego specjalnego konstruktora jest typ StreamingContext, który zawiera

Specjalny konstruktor (2) Drugim parametrem tego specjalnego konstruktora jest typ StreamingContext, który
informacje odnoście źródła lub miejsca przeznaczenia danych.
Najwięcej mówiącą składową tego typu jest właściwość State zwracająca wartość z z enumeracji StreamingContextStates.

Слайд 60

Przykład implementacji interfejsu ISerializable

Przykład implementacji interfejsu ISerializable

Слайд 61

Wynik przykładowej konfiguracji serializacji

Wynikiem przykładowej konfiguracji procesu serializacji będzie następujący plik.
Nazwy jego

Wynik przykładowej konfiguracji serializacji Wynikiem przykładowej konfiguracji procesu serializacji będzie następujący plik.
elementów nie wynikają bezpośrednio z pól danych obiektu, ale zostały odpowiednio skonfigurowane w metodzie GetObiectDate() (podczas serializacji) i specjalnym konstruktorze (podczas deserializacji).

Слайд 62

Konfiguracja za pomocą atrybutów (1)

Drugim sposobem konfiguracji procesu serializacji (preferowanym sposobem) jest

Konfiguracja za pomocą atrybutów (1) Drugim sposobem konfiguracji procesu serializacji (preferowanym sposobem)
definiowanie metod oznaczanych odpowiednimi atrybutami mówiącymi o momencie w procesie serializcji, w którym mają być wywołane.
Atrybuty te to [OnSerializing], [OnSerialized], [OnDeserializing] i [OnDeserialized].
Użycie atrybutów (w porównaniu z implementacją interfejsu ISerializable) jest wygodniejsze, ponieważ nie wymaga bezpośredniej interakcji z typem SerializationInfo.

Слайд 63

Konfiguracja za pomocą atrybutów (2)

Atrybuty te są zdefiniowane w przestrzeni nazw System.Runtime.Serialization.
Metody

Konfiguracja za pomocą atrybutów (2) Atrybuty te są zdefiniowane w przestrzeni nazw
oznaczone tymi atrybutami muszą przyjmować jako parametr typ StreamingContext i nie mogą nic zwracać.
Nie jest wymagane uwzględnianie wszystkich atrybutów związanych z serializacją. Możemy zastosować tylko te, które nas w danej chwili interesują.

Слайд 64

Przykładowa konfiguracji przy użyciu atrybutów

Przykładowa konfiguracji przy użyciu atrybutów
Имя файла: Programowanie-zaawansowane.pptx
Количество просмотров: 41
Количество скачиваний: 0