Das.NET Framework ist eine neue Programmierplattform, die
Microsoft nach mehrjähriger Entwicklung im Januar 2002 in der Version 1.0
freigegeben hat und von der es mittlerweile zahlreiche Versionen gibt. Eine
ausführlichere Darstellung des.NET Frameworks finden Sie in dem Buch
.NET Crashkurs.
Das.NET Framework sollte nicht mit der.NET-Strategie
insgesamt gleichgesetzt werden. Das Framework ist ein Baustein
der.NET-Strategie. Andere Bausteine wie die.NET Enterprise Server basieren
(noch) nicht auf dem.NET Framework.
Geschichte
Die Entwicklung des.NET Framework begann aus der
Entwicklung einer neuen Version des Component Object Models (COM). Sehr schnell
stellte sich heraus, dass.NET sich so weit von COM entfernen würde, dass ein
neuer Name gerechtfertigt ist. Zunächst wurde das Konzept "Next Generation
Windows Service" (NGWS) genannt, seit Juli 2000 verwendet Microsoft den
Begriff.NET Framework.
Installation
Das.NET Framework ist ein kostenloses Add-on für folgende
Betriebssystem: Windows 98, Windows ME, Windows NT 4.0, Windows 2000 und
Windows XP. Ab dem Windows Server 2003 gehört das.NET Framework zum
Standardinstallationsumfang. Das.NET Framework Redistributable ist ein 22 MB
großes Setup. Für Windows CE.NET gibt es eine Light-Version, das sogenannte.NET
Compact Framework.
Werkzeuge
Das Framework Redistributable enthält
Kommandozeilencompiler für die Sprachen Visual Basic.NET, C# und
JScript.NET, sodass dies als Grundpaket für die Entwicklung von.NET-Anwendungen
bereits ausreicht.
Daneben gibt es ebenfalls kostenlos ein 134 MB (englische
Version) bzw. 151 MB (deutsche Version) großes Software Development Kit (SDK)
mit Werkzeugen, Dokumentation und Beispielen. Speziell für die Entwicklung von
Anwendungen für Handheld-Computer, Smartphones und WAP-Handys gibt es das
Mobile Internet Toolkit (MIT). Nicht kostenlos ist die integrierte
Entwicklungsumgebung Visual Studio.NET, die es in drei verschiedenen Versionen
gibt (siehe Grafik).
Abbildung 1:
Funktionsumfang der verschiedenen Werkzeugpakete.

Zwischensprache
Das.NET Framework arbeitet – genau wie die
Programmiersprache Java – mit einer Zwischensprache. Ein
Compiler einer.NET-Sprache erzeugt also nicht einen prozessorspezifischen
Maschinencode, sondern einen plattformunabhängigen Zwischencode. Dieser
Zwischencode heißt Microsoft Intermediate Language (MSIL) und bildet eine so
genannte Assembly.
Erst zur Laufzeit wird dieser MSIL-Code dann in einen
prozessorspezifischen Maschinencode (Native Code) umgewandelt. MSIL-Code wird
aber nicht interpretiert, sondern von einem sogenannten Just-in-Time-Compiler
Stückchenweise umgewandelt und dann ausgeführt. Dabei berücksichtigt der
Just-in-Time-Compiler prozessorspezifische Optimierungsmöglichkeiten.
Dadurch, dass nicht interpretiert, sondern vor der Ausführung kompiliert wird
und der Just-in-Time-Compiler sehr schnell ist, ist der Performance-Verlust
durch die Intermediation sehr gering. Im Zweifel gibt es auch die Möglichkeit,
die das Ergebnis der Kompilierung von MSIL zu Maschinencode zu speichern und
später auszuführen. Dies nennt man ein Native Image. Ein Native Image ist
aber nicht mehr plattformunabhängig.
Die Compiler der Sprachen Visual Basic.NET, J#, C# und
JScript.NET erzeugen immer MSIL-Code. Visual C++ 7.0 erzeugen
wahlweise MSIL-Code oder direkt Native Code.
Abbildung 2:
Intermediation-Konzept im.NET Framework

Einheitliche Laufzeitumgebung
Die Ausführung einer.NET-Anwendung setzt eine
Laufzeitumgebung voraus, die Common Language Runtime (CLR) genannt wird. Die
CLR stellt den Just-in-Time-Compiler und zahlreiche andere Basisdienste bereit,
die von allen.NET-fähigen Sprachen verwendet werden. Dazu gehört zum Beispiel
ein Garbage Collector, Exception Handling, ein Sicherheitssystem und die
Interoperabilität mit nicht.NET-Anwendungen.
Abbildung 3:
Die CLR als einheitliche Laufzeitumgebung

Programmcode, der im Rahmen der CLR ausgeführt wird, heißt
Managed Code (verwalteter Code). Der restliche Code wird entsprechend
Unmanaged Code (nicht-verwalteter Code) genannt.
Die CLR löst das Problem, dass bisher jede Sprache seine
eigene Laufzeitumgebung benötigt hat und diese Laufzeitumgebungen sehr
unterschiedliche Dienste bereitgestellt haben, was deutliche Unterschiede in
der Programmierweise und im Programmierkomfort mit sich gebracht hat.
Wenn eine.NET-Anwendung gestartet wird, ruft Windows nicht
die CLR selbst direkt auf, sondern zunächst einen sogenannten Runtime Host.
Dieser lädt die CLR und übergibt der CLR den Einsprungpunkt für die
Anwendung. Es gibt derzeit drei Runtime Hosts: den Shell Runtime Host, den
Internet Explorer Runtime Host und ASP.NET. In Zukunft werden auch andere
Office- und BackOffice-Anwendungen als Host fungieren können.
Abbildung 4:
Anwendungstypen und Runtime Hosts

Sprachintegration
Das.NET Framework ermöglicht die Zusammenarbeit der
unterschiedlichsten Sprachen. Zusammenarbeit bedeutet dabei nicht nur, dass ein
Aufruf von einem Programmcode möglich ist, der in einer anderen Sprache
geschrieben wurde, sondern auch das in objektorientierten Sprachen eine
Vererbung von Klassen möglich ist, die in einer anderen objektorientierten
Sprache entwickelt wurden.
Basis für diese Sprachintegration ist einerseits die
Zwischensprache MSIL und die CLR und andererseits die so genannte
Common Language Specification (CLS). Die CLS ist ein Regelwerk für Compiler,
das festlegt, wie die Umsetzung von sprachspezifischen Konzepten in die MSIL
erfolgen muss. Kern der CLS ist das
CommonType
System (CTS),
das ein einheitliches System von Datentypen definiert. Denn nur wenn die
verschiedenen Sprachen die gleichen Datentypen verwenden, ist eine problemlose
Integration möglich.
Einheitliche Klassenbibliothek
Ein weiterer Aspekt, der die Programmierung in
verschiedenen Programmiersprachen bislang höchst unterschiedlich gemacht hat,
waren die verschiedenen Funktions- bzw. Klassenbibliotheken. Die.NET Framework
Class Library (FCL) ist eine sehr umfangreiche Klassenbibliothek, die von
allen.NET-Sprachen aus genutzt werden kann. Selbst wenn es in
verschiedenen.NET-Sprachen noch alternative Möglichkeiten für die Ausführung
verschiedener Systemfunktionen (z.B. den Dateisystemzugriff) gibt, sollten die
Klassen der FCL genutzt werden. Dies vermindert den Lern- und
Umstellungsaufwand beim Wechsel auf eine andere Sprache enorm. Die FCL ist
implementiert als eine Reihe von DLLs (Managed Code).
Die FCL enthält in der Version 1.0 genau 2246 öffentliche
Klassen (Umfang des.NET Framework Redistributable, optionale Add-ons nicht
eingerechnet). Um die Übersichtlichkeit zu gewährleisten, sind die FCL-Klassen
in Namensräume eingeteilt. Ein Beispiel für einen FCL-Klassennamen ist
System.Web.UI.Control.
In
ì
Kapitel 7 erfahren Sie
mehr über die Möglichkeiten der FCL.
Code-Sicherheit
Der Schutz vor schädlichen Codes ist ein immer wichtigeres
Thema. Die CLR bietet daher ein neues Sicherheitssystem, das nicht mehr nur die
Rechte des Benutzerkontos, unter dem der Code ausgeführt wird, berücksichtigt,
sondern auch die Herkunft des Programmcodes. Das Sicherheitskonzept wird Code
Access Security (CAS) genannt und ist die Weiterentwicklung des Zonenkonzepts
des Internet Explorers, des Microsoft Authenticode-Verfahrens zur digitalen
Signierung von Programmcode und der Software Restriction Policy (SRP) unter
Windows XP.
Die CLR ermittelt zur Bestimmung der Ausführungsrechte von
Managed Code zunächst die Beweislage (engl. evidence). Zur Beweislage gehören
insbesondere der Autor des Codes (hinterlegt durch das Authenticode-Verfahren)
und der Speicherort des Codes (Zonenkonzept). Auf dieser Basis werden die
Rechte des Codes ggf. eingeschränkt. Selbstverständlich erhält der Code niemals
mehr Rechte als der Benutzer, unter dem der Code läuft, denn das
Windows-Sicherheitssystem wirkt nach wie vor zusätzlich.
Die CAS kann durch die Definition von Code-Gruppen und
Berechtigungssätzen sehr fein konfiguriert werden.
Abbildung 5:
Mischung aus Code-Berechtigungen und Benutzerberechtigungen in der.NET
Framework Code Access Security
Komponentenkonzept
Das.NET Framework ist nicht nur objektorientiert, sondern
auch komponentenorientiert. Im Mittelpunkt des Komponentenkonzepts stehen die
sogenannten Assemblies. Es gibt Assemblies in Form einer EXE oder einer DLL.
Eine DLL-Assembly ist immer eine wieder verwendbare
Softwarekomponente, die von einer anderen Assembly genutzt werden kann. Nur
eine EXE-Assembly lässt sich als eine unabhängige Anwendung starten. Auch eine
EXE-Assembly kann aber Dienste für Andere bereitstellen. Dieses Konzept
unterscheidet sich zunächst nicht von dem Komponentenkonzept unter dem
Component Object Modell (COM).
Eine Assembly ist ein Verbund aus einer oder mehreren
MSIL-Datei, wobei mindestens eine der Dateien eine DLL oder EXE ist. Optional
können auch nicht-MSIL-Dateien, so genannte Ressource-Dateien (z.B. Datenbank-,
Grafik- oder Sound-Dateien), Teil der Assembly sein. Welche Dateien zum Verbund
gehören, wird durch ein Manifest bestimmt. Vor der Ausführung vom Code aus
einer Assembly wird durch die CLR geprüft, ob alle benötigten Dateien in der
gewünschten Version vorhanden sind. Das Manifest ist Teil der DLL oder EXE.
Die folgende Grafik zeigt den Aufbau einer Assembly mit
mehreren Dateien. Die MSIL-Dateien verwendet als Dateiformat das Portable
Executable-Format (PE). Der CLR Header enthält Unmanaged Code zum Laden
des Runtime Hosts. MSIL-Dateien, die kein Manifest enthalten, werden Modul
genannt. Ressourcen können auch in PE-Dateien eingebettet sein.
Abbildung 6:
Aufbau einer Assembly

Auch in COM ab Windows XP gibt es Assemblies und
Manifeste mit ähnlicher Bedeutung. Dort ist eine Assembly ein Verbund aus
mehreren COM-Komponenten zwecks Vermeidung der DLL-Hölle.
Meta-Daten
Jede Assembly und damit auch jeder.NET-Komponente ist
komplett selbstbeschreibend, d.h. es sind ausführliche Informationen über die
in der Komponente enthaltenen Klassen und deren Mitglieder enthalten. Diese
Meta-Daten sind Pflicht. Dies ist ein großer Fortschritt gegenüber COM, wo die
Selbstbeschreibung in Form von Typbibliotheken eine oft vernachlässigte
Option war.
Das Auslesen der Meta-Daten einer.NET-Komponente nennt
man Reflection. Reflection ist integraler Bestandteil des.NET
Frameworks, auf dem vier wichtige Mechanismen beruhen:
¨
Beim Bindungsmechanismus ermittelt die CLR mittels Reflection den
aufzurufenden Programmcode
¨
Die in.NET eingebauten Mechanismen zur
Objektserialisierung benötigen die Meta-Daten, die sie via Reflection
ermitteln. Objektserialisierung ist wiederum die Basis für das Remoting in.NET.
¨
Der Garbage Collector verwendet Reflection um festzustellen,
welche Objekte noch in Benutzung sind.
¨
Mittels des Reflection-Mechanismus kann man dynamisch Code zur
Laufzeit erzeugen.
XCOPY-Deployment und Versionierung
Die meisten.NET-Anwendungen müssen nicht mehr installiert
werden, sondern können einfach an einen beliebigen Ort kopiert und von dort
gestartet werden (Der Begriff XCOPY-Deployment nimmt Bezug darauf, dass zum
Installieren einer.NET-Anwendungen der DOS-Befehl XCOPY ausreicht).
Diese Rückbesinnung auf die Wurzeln von Windows ist möglich
durch den Verzicht auf die Registry als Konfigurationsspeicher und der
Speicherung von DLLs im
/System32-Verzeichnis (oder anderen
zentralen Verzeichnissen). Anwendungsspezifische Konfigurationsinformationen
werden nun in Form von XML-Dateien im Anwendungsverzeichnis abgelegt. Auch alle
benötigten DLLs sollten dort liegen. Nur für wenige Ausnahmen, in denen eine
Mehrfachnutzung einer DLL sinnvoll ist (z.B. bei der Framework Class Library),
gibt es weiterhin einen zentralen Speicherort, den sogenannten Global Assembly
Cache (GAC), der unter
%Windows%/Assembly
liegt. Der GAC ist aber kein einfaches flaches Verzeichnis, sondern eine
komplexe Verzeichnishierarchie, die ermöglicht, gleichnamige DLLs in beliebig
vielen verschiedenen Versionen zu speichern. Dies ist das Ende der DLL-Hölle
(der gegenseitigen Störung von Anwendungen durch die Verwendung einer DLL in
unterschiedlichen, inkompatiblen Versionen).
Abbildung 7:
Ansicht des GAC mit der itvisions.dll in drei versc hiedenen Versionen

Plattformunabhängigkeit
Das.NET Framework ist nicht nur durch die Verwendung der
Zwischensprache MSIL plattformunabhängig. Microsoft hat weite Teile
des.NET Framework standardisieren lassen bei der European Computer
Manufacturers Association (ECMA). Der Standard heißt Common Language
Infrastructure (CLI), ECMA-Standard Nr. 335.
Zum Zeitpunkt der Erstellung dieses Buchs gibt es eine
Implementierung der CLI für FreeBSD. Weitere Implementierungen für
LINUX und für verschiedene UNIX-Derivate sind in Arbeit.
Im Rahmen der Standardisierung hat Microsoft auch weite
Teile des Quellcodes des.NET Frameworks und der Programmiersprache C# für
jedermann zugänglich gemacht (Shared Source CLI).
Von der Standardisierung ausgenommen sind allerdings die
Datenbankschnittstelle ADO.NET (FCL-Namespace
System.Data) und die Benutzeroberflächen-Bibliotheken Windows Forms
(FCL-Namespace
System.Windows.Forms) und
ASP.NET (FCL-Namespace
System.Web).
Interoperabilität
Um die Akzeptanz des.NET Framework zu fördern hat Microsoft
sinnvoller Weise eine Interoperabilität mit klassischen Windows-Anwendungen und
COM-Komponenten sichergestellt. Die CLR ermöglicht sowohl den Aufruf von
klassischen C-Style-DLLs (z.B. dem WIN32-API) als auch COM-Komponenten.
Andersherum kann eine.NET-Anwendung auch als COM-Komponente aufgerufen
werden.
Flexibles Remoting
Der Aufruf von entferntem Code via Remote Procedure Call
(RPC) oder dem auf dem RPC aufsetzenden Distributed COM (DCOM) war aufgrund der
Komplexität und der mangelnden Durchlässigkeit bei Firewalls bislang sehr
unbefriedigend. Das.NET Framework verwendet ein neues, flexibel
Remoting-Konzept mit unterschiedlichen Formaten und Transportwegen.
Ein Formatter ist ein Mechanismus, um ein Objekt in einen
Bytestrom umzuwandeln bzw. zurückzuwandeln. Man spricht in diesem Zusammenhang
auch von Serialisierung/Deserialisierung bzw. Marshaling/Unmarshaling.
Microsoft liefert einen Formatter für ein Binäres Format und einen Formatter
für das Simple Object Access Protocol (SOAP) mit. Ein Channel bietet ein
Transportmedium für serialisierte Objekte an. Microsoft bietet auch hier zwei
eingebaute Alternativen: TCP/IP und HTTP.
Die höchste Geschwindigkeit bietet die Kombination:
BinaryFormatter und TCP/IP. Für die Überwindung von Firewalls ist SOAP/HTTP die
richtige Kombination. Letztere Kombination ermöglicht auch die Nutzung und
Bereitstellung von SOAP-basierten Webservices (siehe
ì
Kapitel 10). Es besteht
die Möglichkeit, eigene Formatter oder Channel für.NET zu entwickeln.
Application Domains
Eine Application Domain ist mit dem.NET Framework neu
eingeführtes Konzept zur Abgrenzung von Anwendungen. Eine Application Domain
ist die Aufteilung eines Prozesses in mehrere Bereiche. Anwendungen, die in
verschiedenen Application Domains laufen, sind voneinander genauso isoliert,
als liefen sie in verschiedenen Prozessen. Application Domain nennt man
auch einen
Pseudo-Prozess.
Der Vorteil einer Application Domain gegenüber der
Erzeugung verschiederner Prozesse ist, dass der Aufwand zur Erzeugung einer
Application Domain und für einen Programmcode-Aufruf zwischen zwei Application
Domains geringer ist als für die Verwendung von Prozessen. Mehrere
Assemblies können sich eine Application Domain teilen.
Abbildung 8:
Application Domains
