Wykład 1a
Co to jest .NET?
Początkowo, gdy nazwa pojawiła się w roku 2000, była to szeroka nazwa marki obejmująca dużą rodzinę nie powiązanych ze sobą technologicznie produktów.
Obecnie nazwa .NET odnosi się w zasadzie do dwóch środowisk:
Platforma .NET Framework
CLR (common language runtime) wspólne środowisko uruchomieniowe - podstawa do budowy aplikacji, podstawa dla wszystkich języków .NET.
Wspólny zbiór typów danych
biblioteka klas .NET Framework - zbiór standardowych klas, które można wykorzystywać w aplikacjach
ASP.NET
Klasy służące do tworzenia aplikacji dostępnych przez przeglądarkę WWW
ADO.NET
Klasy związane z dostępem do danych w relacyjnych bazach danych
Windows Forms
Klasy służące do budowania graficznych interfejsów użytkownika (GUI - graphical user interface)
ASP.NET usługi sieciowe (ASP.NET Web Services)
Klasy służące do tworzenia aplikacji komunikujących się z innymi aplikacjami za pomocą usług sieciowych
Enterprise Services
Klasy udostępniające transakcje rozproszone i inne usługi związane ze skalowalnymi aplikacjami
Inne
Visual Studio - zintegrowane środowisko programistyczne (IDE - integrated development environment). Używane przede wszystkim do pisania aplikacji .NET Framework.
Oprogramowanie korzystające z .NET Framework, korzysta z CLR i jest nazywane kodem zarządzanym.
Kod zarządzany
Kod zarządzany to część programu komputerowego (kodu), który działa pod kontrolą środowiska uruchomieniowego (maszyny wirtualnej).
W przypadku .NET Framework tą maszyną wirtualną jest CLR (Common Language Runtime) w przypadku Javy to JVM (Java Virtual Machine).
W przypadku platformy .NET Framework jest kompilowany i wykonywany przez CLR do kodu języka pośredniego MSIL (Microsoft Intermediate Language). Kod zarządzany kompilowany jest do kodu maszynowego dopiero bezpośrednio przed wykonaniem, jest więc przenośny i dostosowany do każdego procesora i systemu operacyjnego, o ile jest na nim zainstalowane środowisko uruchomieniowe. Program dystrybuowany jest w kodzie pośrednim.
Kod niezarządzany
Kod niezarządzany to kod, który wykonywany jest bezpośrednio przez system operacyjny, poza środowiskiem uruchomieniowym (CLR lub JVM).
Kod niezarządzany musi dostarczać własne wsparcie dla zabezpieczeń, zarządzania pamięcią oraz sprawdzania typów danych - w przeciwieństwie do kodu zarządzanego, który pobiera te informacje ze wspólnego środowiska uruchomieniowego. Kod niezarządzany wykonany jest poza środowiskiem uruchomieniowym.
Aplikacje mogą korzystać tylko z kodu zarządzanego, łączyć kod zarządzany i niezarządzany, korzystać tylko z kodu niezarządzanego.
Kod zarządzany jest zazwyczaj kodem obiektowym, obiekty kodu zarządzanego nazywane są obiektami zarządzanymi. Obiekty zarządzane mogą dziedziczyć z innych obiektów zarządzanych, nawet pisanych w innych językach programowania jeśli tylko są to języki oparte o CLR. W szczególności mogą dziedziczyć i korzystać z kodu bibliotek klas .NET Framework.
Historia - jak było dotychczas
Lata 90 programowanie w środowisku Microsoft to technologie zwane pod nazwą - Windows DNA (Windows Distributed interNet Applications Architecture) marketingowa nazwa dla zbioru technologii Microsoftu, takich jak: COM, DCOM, COM+, ASP, ADO.
Integracja między tymi technologiami nie była wystarczająco duża. Każdy język miał swoje własne biblioteki uruchomieniowe, własne typy danych, własne podejście do budowy GUI I inne różnice. Aplikacje pisane w różnych językach miały różne metody dostępu do usług systemowych.
(Distributed Component Object Model, Active Server Pages, ActiveX Data Objects)
.NET Framework a środowisko Javy.
Istnieją dwa „przeciwstawne” obozy programistyczne: Microsoftu z platformą .NET Framework oraz inni producenci (większość) wspierający środowisko Javy.
Oba środowiska programistyczne są do siebie bardzo podobne. Obsługują te same typy aplikacji, udostępniają standardowe biblioteki.
Biblioteki Javy znana jest pod nazwą Java 2 Enterprise Edition (J2EE lub JEE) i zawiera (biblioteki, technologie) :
Java Server Pages (JSP) - tworzenie skryptów webowych),
Swing - budowa graficznego interfejsu użytkownika (GUI - Graphical User Interface)
JAX-WS - komunikacja oparta na usługach sieciowych
Enterprise JavaBeans (EJB) - budowa skalowalnych aplikacji serwerowych
JDBC - umożliwia dostęp do baz danych
inne
Różnice
środowisko Javy działa na różnych systemach operacyjnych, .NET tylko na Windows
są różni producenci Javy, jeden producent .NET Framework
Istnienie rozwiązań konkurencyjnych jest dobrą rzeczą.
Wspólne środowisko uruchomieniowe - CLR.
CLR - odpowiada wizji jak powinno wyglądać współczesne środowisko programistyczne.
Jest ogólna zgoda co do tego jak powinien wyglądać współczesny język ogólnego przeznaczenia.
Składnia języka (syntaktyka) może być rozmaicie realizowana (nawiasy klamrowe, okrągłe, kropki itp.).
Jednak jest zgoda co do tego jaka powinna być semantyka języka (jakie konstrukcje formalne daj się „powiedzieć” w języku - jakie znaczenia dają się w języku sformułować).
CLR definiuje standardową implementację takiej semantyki.
Każdy język programowania ma:
składnię
zbiór struktur sterujących
zbiór typów danych
sposób dziedziczenia klas
inne
Co dostarcza CLR.
Określa standardowy zbiór typów (CTS - Common Type System) (liczby, łańcuchy znaków, klasy, interfejsy, sposoby dziedziczenia itd.) Typy używane w językach budowanych na bazie CLR.
Nie określa składni - to określającą konkretne języki oparte na CLR
Określa wspólną semantykę dla języków opartych o CLR.
Dostarcza usługę czyszczenia pamięci (garbage collection) automatycznego czyszczenia pamięci z zarządzanych obiektów do których nie ma już referencji
Standardowy format metadanych, informacje o przechowywanych typach wraz ze skompilowanym kodem typu
Wspólny format, zwany pakietem (assembly), służący do organizowania skompilowanego kodu. Pakiet może składać się z bibliotek łączonych dynamicznie (DLL - dynamic link library), plików wykonywalnych (EXE - executable), metadanych dla klas które obejmuje.
Pojedyncza aplikacja może korzystać z jednego lub więcej pakietów.
Środowisko uruchomieniowe służące do wykonywania kodu zarządzanego.
CLR jest podstawą wszystkich komponentów .NET Framework.
Opanowanie języków wykorzystujących .NET, zrozumienie bibliotek klas .NET Framework (miedzy innymi ASP.NET, ADO.NET), wymaga zapoznania się z CLR.
Platforma .NET jest obecnie podstawą nowego oprogramowania dla Windows, tak więc każdy pracujący w środowisku Windows musi zapoznać się z CLR.
Oprogramowanie (kod) tworzony na bazie CLR nazywa się kodem zarządzanym. CLR zarówno umożliwia tworzenie kodu zarządzanego, jak i uruchamianie kodu zarządzanego.
Tworzenie kodu zarządzanego - wspólny system typów (CTS)
Zazwyczaj język programowania definiuje semantykę i składnię języka. Możemy wyobrazić sobie język programowania jako zbiór słów kluczowych z wraz ze składnią, używane do określenia danych i operacji wykonywanych na tych danych.
Składnie różnych języków różnią się, jednak abstrakcje będące podstawą budowy języka są podobne.
W CLR oddzielono te dwie warstwy. CTS definiuje podstawową semantykę języka, definiuje wspólny zbiór typów, nie definiuje słów kluczowych ani składni, pozostawiając to konkretnym językom opartym na CTS. Konkretne języki np. C#, VB, definiują własne słowa kluczowe, własną składnię oraz wykorzystują typy zdefiniowane w CTS (być może tylko niektóre typy).
Typ - ważny element języka programowania.
Typ to zbiór reguł interpretacji wartości przechowywanej w jakimś miejscu pamięci (np., jako wartość zmiennej typu integer, string…). Kompilator języka musi z tych reguł wnioskować np., czy wartość jest z dopuszczalnego zakresu, czy dana operacja jest dopuszczalna na typie itp.
Zbiór typów jest jednym z najistotniejszych elementów CLR.
Języki oparte na CTS udostępniają typy na różne sposoby.
Przestrzenie nazw
Środowisko .NET Framework zorganizowane jest w przestrzeni nazw, logiczne jednostki podziału nazw na grupy. W obrębie danej grupy nazwy muszą być niepowtarzalne. W językach obiektowych taki system używany jest od dawna. Zastosowanie takiego systemu w platformie .NET jest jednak pierwszym przypadkiem zastosowania takiej organizacji w systemie operacyjnym.
Wszystkie obiekty, funkcje, pochodne przestrzenie nazw znajdują się w przestrzeni nazw System.
Pełna nazwa np. funkcji (nazwa skwalifikowana, qualified name) to np. System.Console.Write
Biblioteka klas zorganizowana jest w hierarchię przestrzeni nazw. Każda przestrzeń nazw może zawierać klasy, interfejsy, podrzędne przestrzenie nazw.
Klasa to opis, projekt, szablon dla jednego lub wielu obiektów definiujący zachowanie obiektu. Klasa nie jest obiektem. Obiekt to instancja klasy.
Podstawową przestrzenią nazw jest System to rodzic całej biblioteki klas.
System zawiera bardzo duży zbiór podrzędnych przestrzeni nazw.
Biblioteka nazw klas .NET Framework jest bardzo duża. Jednym z najtrudniejszych elementów w uczeniu się .NET jest opanowywanie potrzebnych fragmentów biblioteki.
Przegląd biblioteki
Zawartość biblioteki klas .NET Framework to
Wycinek (drobny) drzewa przestrzeni nazw biblioteki klas .NET Framework.
Przestrzenie nazw:
System - korzeń drzewa
System.Web - zawiera typy przydatne w tworzeniu aplikacji webowych
System.Web.UI - typy przydatne w tworzeniu w ASP.NET aplikacji dla przeglądarek
System.Web.Services - typy przydatne w tworzeniu aplikacji usług sieciowych
System.Data - tu zawarta jest biblioteka ADO.NET
Zawiera między innymi klasy:
System.Data.Connections - do nawiązywania połączenia systemem zarządzania bazą danych (DBMS)
System.Data.DataSet - do przechowywania i wyniku zapytania (querry)
System.Windows.Forms - typy w tej przestrzeni składają się na Windows Forms i służą do budowy interfejsu użytkownika (GUI) w Windows
System.EnterpriseServices - typy z tej przestrzeni służą do budowy niektórych usług dużych systemów w tym transakcji rozproszonych, zarządzania życiem obiektu i inne…
System.XML - typy w tej przestrzeni służą do pracy z XML tworzenie danych, czytanie danych i inne.
Wprowadzenie do CTS
Każdy typ dziedziczy bezpośrednio, albo pośrednio po typie Object. (System.Object lub System.Object.ValueType))
Każdy typ jest albo typem bezpośrednim, albo typem referencyjnym.
Typ bezpośredni zawiera wartość. To zazwyczaj typ prosty.
Typ referencyjny zawiera referencję (adres) do wartości typu. To zazwyczaj typ skomplikowany.
Te dwa typy mają w inny sposób przydzielaną (alokowaną) pamięć. W kodzie zarządzanym pamięć alokuje się na dwa podstawowe sposoby, oba zarządzane przez CLR: na stosie (stack) i na stercie (heap).
Zmienne alokowane na zarządzanym stosie (stack) zazwyczaj są tworzone, gdy działająca lub wywoływana metoda je utworzy. Pamięć stosu jest automatycznie zwalniana, gdy metoda która utworzyła zmienne kończy swoje działanie. Na stosie umieszczane są typy bezpośrednie.
Zmienne alokowane na stercie (heap) nie zwalniają pamięci, gdy skończy się metoda, która je utworzyła. Pamięć tutaj jest czyszczona przez proces zwany czyszczeniem pamięci (garbage collection). Na stercie umieszczane są typy referencyjne.
Podstawowa różnica to: samodzielny obiekt typu bezpośredniego lokowany jest na stosie (stack), obiekt typu referencyjnego na stosie lokuje referencję (adres) do prawdziwej wartości ulokowanej na stercie (heap), faktyczna wartość lokowana jest na stercie.
CTS definiuje bardzo duży zbiór typów, najważniejszy z nich to typ Object.
Każdy typ CTS dziedziczy po typie Object bezpośrednio lub pośrednio. To w szczególności oznacza, że obiekt tego typu może potencjalnie zawierać dowolną wartość. Typ Object ma kilka metod, które dziedziczą po nim wszystkie typy CTS np. metoda Equals pozwalająca stwierdzić czy dwa obiekty są identyczne, metoda GetType zwracająca typ obiektu do którego została wywołana.
Typy bezpośrednie
Wszystkie typy bezpośrednie dziedziczą po typie ValueType.
Wszystkie typy bezpośrednie są zapieczętowane (sealed) nie mogą być rodzicami, nie można po nich dziedziczyć.
Wszystkie typy bezpośrednie mają nadpisaną Equals.
Przykłady typów bezpośrednich:
Byte - 8-bitowa liczba bez znaku,
Char - 16-bitowy znak Unicode,
Int16, Int32, Int64 - 16-, 32-, 64-bitowe liczby całkowite ze znakiem
UInt16, UInt32, UInt64 - 16-, 32-, 64-bitowe liczby całkowite bez znaku
Single, Double - liczby zmiennoprzecinkowe pojedynczej (32-bity), podwójnej (64-bity) precyzji,
Decimal - liczby dziesiętne 96-bitowe,
Enum - typ wyliczeniowy, dziedziczą po System.Enum, podzbiór jakiegoś zbioru liczb całkowitych, mają znaczące nazwy,
Boolean - prawda lub fałsz.
Składniki typów (type memeber)
Elementy wspólne dla niektórych typów (bezpośrednich i referencyjnych).
Metody (methods) - wykonywalny kod. Metody mogą być przeciążone (overloaded) - może być zdefiniowanych kilka metod o tej samej nazwie, różniących się listą parametrów. Każda metoda ma unikalną sygnaturę (signature). Jeśli metoda napotka błąd generowany jest wyjątek (exeption) z informującą o błędzie.
Pola (fields) - tu przechowywana jest wartość określonego typu.
Zdarzenie (event) - mechanizm służący do komunikacji z innymi typami. Każde zdarzenie ma metody subskrybowania i znoszenia subskrypcji oraz wysyłania (firing) zdarzeń do subskrybentów.
Właściwości (properties) - wartości wraz z metodami do ich odczytywania i zapisywania.
Typy zagnieżdżone (nested types) - typ zdefiniowany wewnątrz innego typu
Składniki typów mogą mieć przypisane cechy.
Na przykład metody, zdarzenia, właściwości mogą być opisane jako:
Abstrakcyjne - nie ma żadnej implementacji
Finalne - nie mogą być nadpisane
Wirtualne - która implementacja zostanie użyta zostanie określone przy uruchomieniu, a nie przy kompilacji
Statyczne - powiązane raczej z typem niż z konkretnym obiektem
Do składników typów mogą być przypisane modyfikatory dostępności (accessibilities). Np.:
Metoda prywatna - dostęp do niej tylko z typu, w którym została zdefiniowana, lub innego typu w nim zagnieżdżonego.
Metoda z dostępnością rodzina (family) - dostęp z typów zagnieżdżonych i dziedziczących
Metoda publiczna (public) - dostęp ze wszystkich możliwych typów.
Typy referencyjne (wybrane)
Class (klasa) - klasa CTS. Może posiadać metody, zdarzenia, właściwości, pola, typy zagnieżdżone….
Widoczność klasy może być public - dostępność dla każdego innego typy, assembly - tylko dla innych klas z tego samego pakietu.
Klasy maja konstruktory będące metodami inicjalizującymi wykonywanymi, gdy tworzony jest obiekt danej klasy
Klasa może dziedziczyć co najwyżej po jednej innej klasie, może być bezpośrednim rodzicem dla co najwyżej jednej dziedziczącej klasy dziecka (dziedziczenie jednokrotne). Po klasie zapieczętowanej nie można dziedziczyć.
Klasa abstrakcyjna - nie może mieć obiektu, służy jedynie jako klasa bazowa do dziedziczenia. Klasa może mieć składniki abstrakcyjne, co oznacza, że wtedy sama jest abstrakcyjna.
Klasa dziedzicząca może nadpisywać metody, właściwości i inne składniki typu rodzica.
Klasa może implementować jeden lub więcej interfejsów.
Interface (interfejs) - interfejs CTS. Może zawierać metody, właściwości, zdarzenia. W przeciwieństwie do klas interfejs może dziedziczyć wielokrotnie. Może dziedziczyć jednocześnie z jednego lub kilku rodziców. Interfejs niczego nie implementuje, implementacja następuje dopiero w odpowiednim typie dziecku. Interfejs dostarcza sposobu na grupowanie definicji typów razem.
Array (tablica) - grupa wartości tego samego typu. Mogą być jedno lub więcej wymiarowe. Wszystkie dziedziczą po wspólnym typie System.Array.
Delegate (delegat) - wskaźnik do metody. Wszystkie delegaty dziedziczą po typie System.Delegate. Najczęściej są używane do obsługi zdarzeń oraz wywołań zwrotnych. Pełnią funkcję podobną do wskaźników w C++. Każdy delegat ma zbiór powiązanych składników zwany listą wywołań. Gdy wywołany zostaje delegat, wywołane są wszystkie składniki z listy wywołań z parametrami które otrzymał delegat.
Języki oparte na CLR, np. C#, VB, konstruują swój własny system typów na bazie typów CTS. Typy te mogą mieć różną reprezentację, jednak ich semantyka jest w zasadzie taka sama.
Konwersja typów bezpośrednich na typy referencyjne - pakowanie (boxing).
Jeśli typ bezpośredni ma być przekazany jako typ referencyjny do jakiejś metody to musi być przekonwertowany w procesie pakowania.
Przekonwertowanie w drugą stronę - odpakowywanie (unboxing)
Języki oparte na CLR ukrywają proces pakowania. Programiści nie muszą żądać wykonania tej transformacji. Referencje do zapakowanych wartości są nieco wolniejsze niż do nie zapakowanych.
Specyfikacja CLS (Common Language Specification).
CTS to duży i skomplikowany zbiór typów. Nie każdy język musi implementować wszystkie typy. Kompromis to CLS definiujący podzbiór CTS do którego musi dostosować się każdy język, który ma współpracować z innymi językami zgodnymi z CLS.
Kompilowanie kodu zarządzanego
Kompilowanie kodu w języku programowania opartego o CLR powoduje utworzenie kodu w języku MSIL oraz metadanych czyli informacji o tych instrukcjach.
Wynikiem kompilacji, bez względu na to w jakim języku kod był napisany początkowo C#, VB czy w innym opartym o CLR jest przetransformowanie wszystkich zawartych w kodzie typów: klas, struktur, liczb, delegatów i innych na kod MSIL oraz na metadane.
Język MSIL (Microsoft Intermediate Language)
Język MSIL jest podobny do zbioru instrukcji abstrakcyjnego procesora - asemblera. Przed wykonaniem kod MSIL tłumaczony jest na kod zbioru instrukcji procesora na którym jest wykonywany.
Programista nie potrzebuje znać, ani w pełni rozumieć MSIL.
Abstrakcyjna maszyna CLR oparta jest o stos, wiele operacji MSIL to operacje zdefiniowane w kategoriach stosu.
Przykładowe instrukcje MSIL:
add - dodanie dwóch wartości z wierzchołka stosu i odłożenie wyniku na stos,
box - konwertowanie na typ referencyjny,
unbox - konwertowanie zapakowanego typu bezpośrednio z powrotem na stos,
br - przekazanie do konkretnej lokacji w pamięci (instrukcja skoku),
call - wywołanie określonej metody,
ldfdl - ładowanie określonego pola obiektu na stos,
ldobj - kopiowanie wartości określonego typu bezpośrednio na stos,
newobj - tworzenie nowego obiektu (typu bezpośredniego)
Widzimy, że jest to język asemblerowy CLR mocno związany z abstrakcjami CTS.
Koncepcja języka MSIL jest podobna do kodu bajtowego (bytecode) języka Java.
Są podobieństwa:
Wirtualna maszyna Javy i CLR definiują wirtualne środowisko oparte na stosie.
Kod bajtowy obecnie obsługuje różne implementacje Javy, MSIL obsługuje różne języki.
Różnice:
Maszyna wirtualna Javy pozwala na kompilację i interpretację kodu bajtowego.
MSIL pozwala tylko na kompilację typu JIT.
Możliwe pisanie (teoretycznie raczej) kodu niskiego poziomu .NET Framework, Microsoft udostępnia asembler MSIL o nazwie Ilasm.
Po co używać MSIL, język pośredni.
Potencjalna przenośność
Możliwość zwiększenia bezpieczeństwa i niezawodności. Weryfikacja ze względu na bezpieczeństwo typów ładowanych do pamięci, możliwość wyeliminowania pewnej klasy błędów i zagrożeń.
Potencjalna wada spowolnienie związane z pierwszą kompilacją.
Metadane
Kompilowanie kodu zarządzanego tworzy kod w języku MSIL oraz metadane.
Metadane to informacje o typach zdefiniowanych w powiązanym kodzie zarządzanym, przechowywane są w tym samym pliku co wygenerowany z tych plików MSIL
Co zawierają metadane
Opisują typy zawarte w module, w tym:
nazwę typu,
widoczność typu (public, assembly),
typ, po którym dziedziczy, jeśli taki występuje,
interfejsy, implementowane przez typ,
metody, implementowane przez typ,
właściwości, udostępniane przez typ,
zdarzenia, które typ może wygenerować,
inne szczegółowe informacje.
Metadane występują zawsze. Metadane pozwalają narzędziom na dostęp do nich. Visual Studio wykorzystuje metadane do dostarczenia IntelliSense, programista może w ten sposób dostawać podpowiedzi jakie metody są dostępne dla właśnie wpisanej nazwy klasy.
Metadane mogą być też badane, pokazywane deasmblerem. Microsoft udostępnia deasembler MSIL o nazwie Ildasm.
Metadane mają też atrybuty. Atrybuty są wartościami przechowywanymi w metadanych. Mogą być odczytywane i wykorzystywane do kontrolowania różnych aspektów wykonywania kodu. Mogą być używane do przy transakcjach, w związku z bezpieczeństwem itd.…
Organizacja kodu zarządzanego - pakiety (assembly)
Kompletna aplikacja składa się z różnych plików, zawierających kod modułów DLL lub EXE, pliki zawierające jakieś zasoby np. obrazki. W aplikacja .NET Framework pliki tworzące logiczną całość łączone są w pakiety.
Pakiet to konstrukcja logiczna, a nie jeden główny plik. Manifest pakietu określa przynależność do pakietu. W manifeście pakietu zawiera informacje o modułach i innych plikach należących do pakietu, Manifest jest zawarty w jednym z plików pakietu.
Pakiet może składać się z jednego pliku lub z kilku plików
Wśród informacji umieszczonych w manifeście pakietu są:
Nazwa pakietu.
Pakiet ma nazwę tekstową, pełną nazwę (nazwa pakietu, jego numer wersji, kultury, którą obsługuje jeśli jest obecna) może też mieć silną nazwę (trzy elementy pełnej nazwy, cyfrowy podpis obliczony na bazie pakietu i klucza prywatnego oraz udostępnionego klucza publicznego). Nazwa silna jest unikalna. W samym pakiecie może być osadzony certyfikat jednostki tworzącej podpis cyfrowy. Pozwala to osobie chcącej wykorzystać pakiet na weryfikację i podjęcie decyzji o uruchomieniu.
Numer wersji pakietu - forma numeru to:
<główny numer>.<drugorzędny numer>.<numer kompilacji>.<wersja>
Np.: 1.3.0189.0
numery wersji nadawane są w zakresie całego pakietu, a nie poszczególnych modułów
Kultura pakietu - wskazuje na kulturę bądź język, obsługujące pakiet.
Lista plików zawartych w pakiecie wraz z zawartością sumy kontrolnej obliczonej z tych plików.
Informacja, od jakich innych pakietów zależy pakiet, numery wersji każdego z nich
Istotnym następstwem sposobu ustrukturyzowania pakietów jest to, że w przeciwieństwie do klas COM, klasy CLR nie mają powiązanych z nimi wpisów w rejestrze. Chyba, że ze względu na zgodność ze starszymi wersjami oprogramowania są też udostępniane jako COM.
CLR gdy ma odnaleźć klasę w pakiecie nie szuka jej w rejestrze lecz szuka przy pomocy manifestów według ustalonego algorytmu.
Pominięcie wpisów do rejestru oznacza, że instalowanie pakietu polega na skopiowaniu do wymaganego katalogu, bez wpisów do rejestrów. Zaś odinstalowanie to usunięcie odpowiednich plików.
Nie następuje modyfikacja rejestrów.
Wykonywanie kodu zarządzającego.
Ładowanie pakietów.
Uruchamiamy aplikację. Wymagane pakiety są odnajdywane i ładowane do pamięci w miarę tego jak są potrzebne.
CLR odnajduje wymagane pakiety. Odnajdywanie (identyfikacja) to dosyć skomplikowany proces (ustalanie wymaganej wersji, przeszukiwanie odpowiednich manifestów).
Kompilowanie kodu w MSIL
Kompilator tworzący kod zarządzany, zawsze generuje MSIL. Jednak MSIL nie może być uruchomiony na żadnej maszynie. Musi być skompilowany do kody rdzennego danego procesora. Może to być wykonane na dwa sposoby:
Metoda po metodzie w trakcie wykonywanie programu
W całości przed wykonaniem pakietu.
Najczęstszy sposób kompilowania MSIL do kodu rdzennego to pozwolenie CLR by załadował pakiet, a następnie kompilowanie każdej metody za pierwszym razem gdy jest wywoływana. Proces ten nazywany jest kompilacją w locie (JIT - just in time).
Przykład kolejne rysunki:
Metoda po skompilowaniu JIT jest weryfikowana pod względem bezpieczeństwa typów.
Kod skompilowany nie jest zapisywany na dysku.
Możliwe też jest utworzenie kodu rdzennego w całości za pomocą narzędzia Native Image Generator (NGEN).
Zabezpieczanie pakietów.
Pakiet definiuje między innymi zakres bezpieczeństwa.
CLR implementuje dwa rodzaje typów bezpieczeństwa dla pakietów:
Oparte na uprawnieniach kodu (CAS - Code Access Security)
Oparte na rolach (RBS - Role Based Security)
Bezpieczeństwo oparte na uprawnieniach kodu.
Dotychczas była reguła wszystko albo nic. Mogłem nie uruchamiać kodu, ale gdy uruchomiłem nie mogłem kontrolować co robi.
Kod oparty na CLR uzależniony jest od dwóch czynników: tego jakich uprawnień żąda kod, oraz tego jakie uprawnienia zostały mu przyznane w polityce bezpieczeństwa obowiązującej w chwili wykonywania kodu.
Pakiet dostarcza dowody tego kto go stworzył:
Tożsamość wydawcy pakietu, cyfrowy podpis
Tożsamość pakietu reprezentowana prze silną nazwę
Adresu strony internetowej skąd została pobrana
Dokładnego adresu URL, skąd adres został pobrany
Strefy skąd pakiet został pobrany.
Kiedy pakiet zostanie załadowany CLR bada dostarczony dowód. Sprawdza żądania pakietu z polityką bezpieczeństwa ustawioną na maszynie.
Bezpieczeństwo oparte na rolach (RBS)
Kontrola oparta o tożsamość użytkownika.
Tożsamość użytkownika określona jest przez obiekt identity
Autoryzacja może być dokonana: na podstawie
identyczności zalogowania,
mechanizmu Kerberos,
w Internecie inny mechanizm np. Passport
Domeny aplikacji
CLR jest implementowane jako biblioteka DLL. Oznacza to, że zazwyczaj istnieje plik EXE zawierający CLR i biblioteki DLL z pakietu który jest ładowany.
Środowisko wykonawcze ładuje i inicjalizuje CLR, a następnie przenosi sterowanie do kodu zarządzanego.
Środowisko wykonawcze w ramach swojego procesu tworzy jedną lub kilka domen aplikacji (app domains). Proces domena aplikacji izoluje aplikację od innych aplikacji z innych domen.
Literatura:
ASP.NET 2.0 Projektowanie aplikacji internetowych, R.Connolly, Prentince Hall, Helion 2008
Zrozumieć platformę .NET, wydanie II, D.Chappell Adison-Wesley, Helion 2007
Technologie ASP.NET I ADO.NET, J.Matulewski, S.Orłowski, Helion 2007
Visual C# krok po kroku, J.Stroup, Microsoft Corporation, Microsoft Press 2006
Podstawy Microsoft .NET, D.S.Platt, Wydawnictwo RM 2001
Skany zamieszczone w wykładzie:
Zrozumieć platformę .NET, wydanie II, D.Chappell Adison-Wesley, Helion 2007
Wykład 1a.doc Aplikacje internetowe
P. Zaremba 14/15