Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Waldemar Bartyna 1 Programowanie zaawansowane Refleksja.

Podobne prezentacje


Prezentacja na temat: "Waldemar Bartyna 1 Programowanie zaawansowane Refleksja."— Zapis prezentacji:

1 wbartyna@gmail.com Waldemar Bartyna 1 Programowanie zaawansowane Refleksja

2 wbartyna@gmail.com Waldemar Bartyna Wprowadzenie  Pakiety są podstawowymi jednostkami wdrożeniowymi w świecie.NET.  Za pomocą narzędzi środowiska programistycznego (IDE), jesteśmy w stanie obejrzeć wszystkie typy zdefiniowane w pakietach.  Zewnętrzne narzędzia, takie jak ildasm i reflector pozwalają na przejrzenie kodu CIL, metadanych typów i manifestu pakietu dla wskazanych binariów.NET. 2

3 wbartyna@gmail.com Waldemar Bartyna Zagadnienia (1)  Oprócz tego, dostępnego w czasie projektowania, sposobu przeglądania zawartości pakietów, mamy również możliwość programowego dostępu do tych informacji wykorzystując przestrzeń nazw System.Reflection.  Pierwszym omawianym zagadnieniem będzie rola refleksji i konieczność definiowania metadanych.  Pozostałe zagadnienia będą ściśle związane z usługami refleksji. 3

4 wbartyna@gmail.com Waldemar Bartyna Zagadnienia (2)  Wykorzystanie dynamicznego ładowania i późnego wiązania w celu aktywowania typów, o których nie mamy żadnej wiedzy w czasie kompilacji.  Dodawanie własnych metadanych do pakietu poprzez użycie dostarczanych przez system lub własnoręcznie zdefiniowanych atrybutów.  Przykładowa aplikacja pokazująca zastosowanie poznanych mechanizmów. 4

5 wbartyna@gmail.com Waldemar Bartyna Metadane i refleksja 5

6 wbartyna@gmail.com Waldemar Bartyna Znaczenie metadanych (1)  Zdolność kompletnego opisywania typów (klas, interfejsów, struktur, enumeracji i delegatów) jest jednym z kluczowych elementów platformy.NET.  Wiele technologii.NET, takich jak: Serializacja obiektów, Zdalne wywołania, XML-owe usługi sieciowe, Windows Communication Fundation (WCF) wymaga możliwości wykrywania formatu typów w czasie wykonania. 6

7 wbartyna@gmail.com Waldemar Bartyna Znaczenie metadanych (2)  Na metadanych opiera się również: Współpraca w ramach wielojęzykowej platformy, Liczne usługi kompilatora, Możliwości narzędzi takich jak IntelliSense.  Dzięki tak dużemu zastosowaniu metadanych są one znane i stosowane nie od dziś, w środowiskach takich jak np.: Java, CORBA, COM. 7

8 wbartyna@gmail.com Waldemar Bartyna Zawartość metadanych (1)  Metadane przechowywane są w formie binarnej pozwalającej na duże upakowanie informacji.  Programy służące do ich przeglądania wyświetlają te informacje w bardziej opisowej formie, czytelnej dla człowieka.  Każdy typ zdefiniowany w aktualnym pakiecie jest udokumentowany za pomocą elementu TypeDef #n (ang. type definition).  Typ, do którego się odnosimy jest udokumentowany za pomocą elementu TypeRef #n (ang. type reference). 8

9 wbartyna@gmail.com Waldemar Bartyna Zawartość metadanych (2)  W sumie, metadane to zbiór tabel, zawierających ściśle sformatowane opisy wszystkich definicji typów i elementów powiązanych.  Przykładowy opis typu (enumeracji): 9

10 wbartyna@gmail.com Waldemar Bartyna  Definicja klasy i pola danych Opis elementu TypeDef (1) 10

11 wbartyna@gmail.com Waldemar Bartyna Opis elementu TypeDef (2)  Definicja metody 11

12 wbartyna@gmail.com Waldemar Bartyna Opis elementu TypeDef (3)  Definicja właściwości. 12

13 wbartyna@gmail.com Waldemar Bartyna Opis elementu TypeRef  Metadane zawierają wykaz typów zdefiniowanych w zewnętrznych pakietach, a do których odnosimy się w naszym projekcie. 13

14 wbartyna@gmail.com Waldemar Bartyna Opis elementu Assembly  Do metadanych należy również opis pakietu (jego manifest). 14

15 wbartyna@gmail.com Waldemar Bartyna Opis elementu AssemblyRef  Metadane zawierają także informacje o pakietach, z których korzystamy. 15

16 wbartyna@gmail.com Waldemar Bartyna Opis elementu User Strings  Każdy łańcuch znakowy, zapisany w kodzie bazowym naszego projektu jest również zapisywany w metadanych 16

17 wbartyna@gmail.com Waldemar Bartyna Refleksja  Refleksja jest procesem odkrywania i wykorzystywania typów w czasie wykonania programu.  Korzystając z usług refleksji, możliwe jest programowe zdobycie tej samej wiedzy o metadanych, którą uzyskujemy stosując zewnętrzne programy.  Informacje te są prezentowane w postaci odpowiednio zaprojektowanych klas.  Typy reprezentujące te informacje, zostały zdefiniowane w przestrzeni naw System.Reflection. 17

18 wbartyna@gmail.com Waldemar Bartyna Zastosowanie refleksji  Za pomocą refleksji możemy (np.): Pozyskać listę wszystkich typów zawartych w danym pakiecie, włącznie z: Metodami, Polami danych, Właściwościami. Zdarzeniami zdefiniowanymi w ramach danego typu. Dynamicznie odkryć zbiór interfejsów wspieranych przez dany typ, parametry metod, I inne powiązane z tym szczegóły (klasy bazowe, informacje o przestrzeniach nazw, dane z manifestu itd.). 18

19 wbartyna@gmail.com Waldemar Bartyna Przestrzeń nazw System.Reflection 19 Nazwa TypuZnaczenie AssemblyTyp ten zawiera wiele metod pozwalających na ładowanie, przeglądanie i manipulowanie pakietami. AssemblyNamePrzechowuje informacje związane z identyfikacją pakietu (nazwa, wersja, lokalizacja itd.) EventInfoPrzechowuje informacje o danym zdarzeniu. FieldInfoPrzechowuje informacje o danym polu. MemberInfoAbstrakcyjna klasa bazowa, która definiuje wspólne zachowanie dla typów EventInfo, FieldInfo, MethodInfo, i PropertyInfo. MethodInfoPrzechowuje informacje o danej metodzie. ModulePozwala na dostęp do danego modułu w wieloplikowym pakiecie. ParameterInfoPrzechowuje informacje o danym parametrze. PropertyInfoPrzechowuje informacje o danej właściwości.

20 wbartyna@gmail.com Waldemar Bartyna Klasa System.Type  Aby móc wykorzystać klasy zdefiniowane w przestrzeni nazw System.Reflection, musimy również znać typ System.Type.  Klasa System.Type definiuje wiele składowych, które można użyć do zapoznania się z metadanymi typu.  Duża część tych składowych zwraca obiekty typów zdefiniowanych właśnie w przestrzeni nazw System.Reflection. 20

21 wbartyna@gmail.com Waldemar Bartyna Właściwości klasy System.Type 21 Nazwa właściwościZnaczenie IsAbstract IsArray IsClass IsCOMObject IsEnum IsGenericTypeDefinition IsGenericParameter IsInterface IsPrimitive IsNestedPrivate IsNestedPublic IsSealed IsValueType Te właściwości (nie wszystkie zostały tu przedstawione) pozwalają na zdobycie wielu informacji o podstawowych cechach danego typu (czy jest on abstrakcyjną klasą, zagnieżdżoną klasą, tablicą, itd.).

22 wbartyna@gmail.com Waldemar Bartyna Metody klasy System.Type 22 Nazwa metodyZnaczenie GetConstructors() GetEvents() GetFields() GetInterfaces() GetMembers() GetMethods() GetNestedTypes() GetProperties() Metody te pozwalają na pobranie tablicy reprezentującej elementy (interfejsy, metody, właściwości, itd.), o których chcemy pozyskać informacje. Każda z tych metody posiada również swoją pojedynczą odmianę, która zwraca konkretny element na podstawie wskazanej nazwy, a nie tablicę elementów danego rodzaju. FindMembers() Ta metod zwraca tablicę obiektów MemberInfo w oparciu o zadane kryteria. GetType() Ta statyczna metoda zwraca instancję Typu o zadanej poprzez łańcuch znaków nazwie. InvokeMember() Ta metoda umożliwia realizację późnego wiązania.

23 wbartyna@gmail.com Waldemar Bartyna Metoda System.Object.GetType()  Instancję klasy Type możemy uzyskać na kilka sposobów.  Czego nie możemy zrobić,to ją zdefiniować poprzez słowo kluczowe new, ponieważ klasa Type jest klasą abstrakcyjną.  Klasa System.Object definiuje metodę GetType(), która zwraca instancję obiektu klasy Type, reprezentującą metadane wskazanego typu. W tym przypadku musimy znać dany typ już podczas kompilacji. 23

24 wbartyna@gmail.com Waldemar Bartyna Metoda Type.GetType() (1)  Aby zdobyć informacje o typie w bardziej elastyczny sposób, możemy skorzystać ze statycznej metody GetType() zdefiniowanej w klasie System.Type.  Parametrem tej metody jest łańcuch znaków reprezentujący pełną kwalifikowaną nazwę danego typu.  Używając tego podejścia, nie musimy znać definicji danego typu w czasie kompilacji. Sama nazwa typu może być, na przykład, dostarczona poprzez plik konfiguracyjny. 24

25 wbartyna@gmail.com Waldemar Bartyna Metoda Type.GetType() (2)  Metoda GetType() posiada przeładowaną wersję z dwoma dodatkowymi argumentami logicznymi. Pierwszy decyduje o tym, czy odpowiedni wyjątek ma być zgłoszony w przypadku nieodnalezienia odpowiedniego typu. Drugi mówi o tym, czy metoda ma być niewrażliwa na wielkość liter w nazwie typu. 25

26 wbartyna@gmail.com Waldemar Bartyna Metoda Type.GetType() (3)  W poprzednim przykładzie nic nie wskazywało na pakiet, w którym dany typ jest zdefiniowany. W takim przypadku zakłada się, że dany typ znajduje się w aktualnie tworzonym pakiecie.  Gdy chcemy pobrać informacje z zewnętrznego pakietu, jego nazwę podajemy jako część łańcucha znaków definiującego nazwę typu, oddzieloną przecinkiem od samej kwalifikowanej nazwy typu.  Dodatkowo, możemy użyć znaku „+” pozwalającego na pobranie zagnieżdżonej definicji typu. 26

27 wbartyna@gmail.com Waldemar Bartyna Operator typeof  Ostatnim sposobem uzyskania informacji o typie, jest wykorzystanie operatora typeof.  Podobnie, jak w przypadku metody Type.GetType() nie musimy tworzyć obiektu danego typu, aby pobrać o nim informacje.  Jednakże w tym przypadku kompilator musi mieć dostęp do definicji danego typu, ponieważ argumentem tej metody jest silnie typowana nazwa typu, a nie łańcuch znaków. 27

28 wbartyna@gmail.com Waldemar Bartyna Dynamiczne ładowanie pakietów i późne wiązanie 28

29 wbartyna@gmail.com Waldemar Bartyna Dynamiczne ładowanie pakietów  Dynamicznym ładowaniem nazywamy czynność ładowania zewnętrznego pakietu na żądanie.  Przestrzeń nazw System.Reflection definiuje klasę Assembly, reprezentującą informacje i metody dotyczace pakietów..  Klasa ta definiuje metody (w szczególności Load() i LoadFrom()), które pozwalają na programowe wykorzystanie informacji, najczęściej definiowanych w pliku konfiguracyjnym po stronie klienta. 29

30 wbartyna@gmail.com Waldemar Bartyna Przeglądarka zewnętrznych pakietów (1) 30

31 wbartyna@gmail.com Waldemar Bartyna Przeglądarka zewnętrznych pakietów (2) 31

32 wbartyna@gmail.com Waldemar Bartyna Późne wiązanie  Późne wiązanie to technika pozwalająca na stworzenie instancji danego typu i wywołanie jego składowych w czasie wykonania programu bez posiadania wiedzy o tym typie w czasie kompilacji.  Jeżeli jest to tylko możliwe, powinno się stosować „wczesne wiązanie” (czyli dodanie do projektu odwołania do odpowiedniego pakietu i tworzenie obiektów poprzez new). Pozwala ono na wykrycie błędów w czasie kompilacji.  Jednakże, późne wiązanie odgrywa krytyczną role podczas tworzenia rozszerzalnych aplikacji. 32

33 wbartyna@gmail.com Waldemar Bartyna Klasa System.Activator  Kluczową klasą używaną do późnego wiązania jest klasa System.Activator.  Definiuje ona mały zbiór składowych, z których cześć jest używana w zdalnym API.NET.  Interesującą nas metodą jest Activator.CreateInstancce(), która jest stosowana do utworzenia instancji typu w późnym wiązaniu.  Metoda ta posiada wiele przeładowanych wersji. Najprostsza z nich przyjmuje jako argument obiekt klasy Type, reprezentujący typ, którego instancję chcemy stworzyć „w locie”. 33

34 wbartyna@gmail.com Waldemar Bartyna Przykład utworzenia instancji „w locie” 34

35 wbartyna@gmail.com Waldemar Bartyna Późne wywołanie metody (1)  Aby wywołać składową utworzonego w ten sposób obiektu, należy posłużyć się refleksją. 35

36 wbartyna@gmail.com Waldemar Bartyna Późne wywołanie metody (2)  Parametry do późno wywoływanej metody przekazujemy jako tablicę obiektów klasy System.Object. 36

37 wbartyna@gmail.com Waldemar Bartyna Atrybuty 37

38 wbartyna@gmail.com Waldemar Bartyna Atrybuty (1)  Zadaniem kompilatora jest wygenerowanie metadanych opisujących wszystkie zdefiniowane i wykorzystywane typy.  Platforma.NET umożliwia również programiście dodanie własnych informacji do metadanych za pomocą atrybutów.  Atrybuty to po prostu adnotacja kodu, która może być zastosowana do: Typu (klasy, interfejsu, struktury, itd.), Składowej (właściwości, metody, itd.), Pakietu, Modułu. 38

39 wbartyna@gmail.com Waldemar Bartyna Atrybuty (2)  Atrybuty na platformie.NET to klasy, które rozszerzają abstrakcyjna klasę bazową System.Attribute.  W różnych przestrzeniach nazw zdefiniowanych jest wiele atrybutów, z których możemy skorzystać.  Dodatkowo, możemy również tworzyć własne atrybuty.  Informacje umieszczone w metadanych przy pomocy atrybutów są praktyczne bezużyteczne do momentu, w którym inny program użyje jawnie refleksji do odczytania tych danych. 39

40 wbartyna@gmail.com Waldemar Bartyna Atrybuty standardowe 40 AtrybutyZnaczenie [CLSCompilet] Wymusza sprawdzenie zgodności danego elementu ze specyfikacją CLS. [DllImport] Pozwala na odwołania do niezarządzanego kodu C i C++. [Obsolete] Oznacza dany element jako „przestarzały”. [Serializable] Oznacza daną klasę lub strukturę jako serializowalną (jej stan może być przekazany do strumienia. [NonSerialized] Oznacza, że dana składowa powinna być pominięta w procesie serializacji. [WebMethod] Oznacza metodę jako mogącą zostać wywołaną poprzez żądanie HTTPi instruuje CLR do serializacji wartości zwracanej przez daną metodę do XML-a.

41 wbartyna@gmail.com Waldemar Bartyna Przykład użycia atrybutu (1)  Oznaczamy definiowaną klasę, jako mogącą zostać zapisaną do strumienia. 41

42 wbartyna@gmail.com Waldemar Bartyna Przykład użycia atrybutu (2)  Pojedynczy element, może być oznaczony kilkoma atrybutami.  Atrybuty te można również zapisać w następującej postaci: 42

43 wbartyna@gmail.com Waldemar Bartyna Konstruktor atrybutu  Atrybuty (jak wszystkie inne klasy), mogą posiadać konstruktory.  Należy pamiętać, że w momencie nadania wartości parametrowi konstruktora, nie jest alokowany nowy obiekt w pamięci.  Czynność ta jest realizowana dopiero w momencie odczytania atrybutu poprzez refleksję. 43

44 wbartyna@gmail.com Waldemar Bartyna Skrótowy zapis  Równie dobrze, można w nazwie atrybutu użyć pełnej nazwy klasy.  Należy pamiętać, że nie wszystkie języki platformy.NET wspierają skrótowy zapis atrybutów (tak, jak czyni to C#). 44

45 wbartyna@gmail.com Waldemar Bartyna Atrybut w akcji  Następująca linie kodu:  Spowoduje pojawienie się ostrzeżeń 45

46 wbartyna@gmail.com Waldemar Bartyna Podsumowanie atrybutów  Atrybuty prowadzą do dodanie informacji do metadanych.  Atrybuty są klasami dziedziczącymi po klasie System.Attribute.  Atrybuty są praktycznie bezużyteczne do momentu, gdy inny program odwoła się do nich poprzez refleksję.  W C#, atrybuty definiujemy za pomocą nawiasów kwadratowych. 46

47 wbartyna@gmail.com Waldemar Bartyna Niestandardowe atrybuty (1)  Definiujemy niestandardowy atrybut. 47

48 wbartyna@gmail.com Waldemar Bartyna Niestandardowe atrybuty (2)  Użycie niestandardowego atrybutu. 48

49 wbartyna@gmail.com Waldemar Bartyna Nazwane właściwości  W przypadku pierwszej klasy, atrybut zdefiniowano za pomocą nazwanej właściwości  Nazwana właściwość definiowana jest w postaci par nazwa/wartość.  W momencie zastosowania refleksji, wskazana wartość przekazywana jest do odpowiedniej właściwości.  Wymaga to oczywiście, aby w klasie atrybutu dana właściwość była zdefiniowana.  Atrybuty przy pozostałych klasach definiowane są za pomocą konstruktorów. 49

50 wbartyna@gmail.com Waldemar Bartyna Ograniczenie użycia atrybutu  Możliwe użycie atrybut ograniczamy za pomocą atrybutu AttributeUsage i enumeracji AttributeTargets. 50

51 wbartyna@gmail.com Waldemar Bartyna Atrybuty i wczesne wiązanie 51

52 wbartyna@gmail.com Waldemar Bartyna Atrybuty i późne wiązanie (1) 52

53 wbartyna@gmail.com Waldemar Bartyna Atrybuty i późne wiązanie (2) 53

54 wbartyna@gmail.com Waldemar Bartyna Przykład rozszerzalnej aplikacji 54

55 wbartyna@gmail.com Waldemar Bartyna Tworzenie rozszerzalnej aplikacji  Po pierwsze, rozszerzalna aplikacja musi zapewnić pewien rodzaj wejścia, aby umożliwić użytkownikowi podłączenie pluginu (takie jak okienko dialogowe lub parametr w linii poleceń). To wymaga dynamicznego ładowania.  Po drugie, rozszerzalna aplikacja musi być w stanie ustalić, czy moduł wspiera właściwą funkcjonalność (np. poprzez zbiór wymaganych interfejsów). To pozwoli na podłączenie go do środowiska. To wymaga refleksji.  W końcu, rozszerzalna aplikacja musi pozyskać odwołanie do wymaganej infrastruktury (np. zbiór interfejsów) i wywołać jego składowe w celu „wystartowania” jego funkcjonalności. To wymaga późnego wiązania 55

56 wbartyna@gmail.com Waldemar Bartyna Pakiety zdefiniowane w przykładzie  CommonSnappableTypes.dll – zawiera typy wykorzystywane przez wszystkie pluginy.  CSharpSnapIn.dll – plugin w języku C#,  VbNetSnapIn.dll - plugin w języku Visual Basic,  MyExtendableApp.exe – aplikacja Windows Forms będzie właśnie rozszerzalną aplikacją, do której zostały napisane pluginy. 56

57 wbartyna@gmail.com Waldemar Bartyna CommonSnappableTypes 57

58 wbartyna@gmail.com Waldemar Bartyna CSharpSnapIn 58

59 wbartyna@gmail.com Waldemar Bartyna VbNetSnapIn 59

60 wbartyna@gmail.com Waldemar Bartyna MyExtendableApp (aplikacja Windows Forms) 60

61 wbartyna@gmail.com Waldemar Bartyna MyExtendableApp (1)  Zdarzenie kliknięcia na element w menu: 61

62 wbartyna@gmail.com Waldemar Bartyna MyExtendableApp (2)  Metoad loadExternalModule() (1) 62

63 wbartyna@gmail.com Waldemar Bartyna MyExtendableApp (3)  Metoad loadExternalModule() (2) 63

64 wbartyna@gmail.com Waldemar Bartyna MyExtendableApp (4)  W celu wyświetlenia informacji przekazanych poprzez atrybut, dodajemy do metody LoadExternalModul() wywołanie metody DisplayCompanyData(). 64

65 wbartyna@gmail.com Waldemar Bartyna MyExtendableApp (5)  Definicja metody DisplayCompanyData(). 65

66 wbartyna@gmail.com Waldemar Bartyna MyExtendableApp (6) 66

67 wbartyna@gmail.com Waldemar Bartyna 67 Dziękuję za uwagę


Pobierz ppt "Waldemar Bartyna 1 Programowanie zaawansowane Refleksja."

Podobne prezentacje


Reklamy Google