WCF: Multitalent für SOA-Umgebungen
Artikel erschienen in Swiss IT Magazine 2006/15
In den vergangenen Jahren haben vor allem zwei Technologien respektive Architekturen die Welt der Softwareentwicklung massgeblich geprägt: Web Services und Service-orientierte Architekturen (SOA). Während Web Services von vornherein als integrale Komponente in .Net unterstützt wurden, bietet Microsoft nun mit der Windows Communication Foundation (WCF) Unterstützung für SOA. Was sich zunächst so anhört, als ob SOA einfach eine weitere Technologie wäre, die unterstützt werden müsse, präsentiert sie sich bei genauerem Hinsehen als Architekurmodell, um Applikationen miteinander zu verknüpfen. SOA bedeutet, dass alle in einem verteilten System enthaltenen Applikationen Dienste bereitstellen, die von den anderen Anwendungen genutzt werden können.
Während Web Services bei der Einführung von .Net als Allheilmittel dargestellt wurden, hat sich inzwischen gezeigt, dass Web Services einfach eine Möglichkeit sind, Dienste bereitzustellen. Doch auch eine SQL-Server-Datenbank kann man als Dienst sehen, eine Applikation, die über .Net Remoting angesprochen wird, oder eine klassische Anwendung, die auf Windows Forms oder ASP .Net aufbaut.
Insofern besteht SOA aus mehr als nur Web Services, letztlich geht es bei SOA um die Verknüpfung und die Integration von Applikationen, die sich an verschiedenen Standorten befinden. Dabei müssen diese Standorte nicht zwingend physikalisch voneinander getrennt sein, auch verschiedene Prozesse innerhalb eines Systems können zwei Standorte sein.
Die Frage, die sich einem Entwickler also stellt, ist, wie .Net den Aufbau von Services sowie deren Kommunikation und Integration unterstützt. Bislang gibt es dazu verschiedene Techniken, von denen einige schon erwähnt wurden: .Net Remoting, Web Services, Microsoft Message Queue (MSMQ) oder das SMTP-Protokoll.
Als Entwickler hat man demnach eine breite Palette an Technologien zur Verfügung, die alle jeweils ihre spezifischen Vor- und Nachteile haben. Der grosse Nachteil an dieser Mannigfaltigkeit ist, dass sie unterschiedlich implementiert werden – Code, der eine Nachricht über die MSMQ versendet, sieht anders aus als Code, der eine Message als E-Mail über SMTP verschickt.
Tritt man einen Schritt zurück und abstrahiert, so erfüllen diese Technologien alle den gleichen Zweck: Nachrichten von einer Komponente zu einer anderen zu übertragen oder – anders formuliert – verschiedene Services dazu zu bringen, miteinander zu sprechen. Lediglich die Sprache, in der zwei Services miteinander kommunizieren, unterscheidet sich. Genau an dieser Stelle setzt die Windows Communication Foundation (WCF) den Hebel an.
In der Windows Communication Foundation gibt es zunächst einmal Services, die von einer
x-beliebigen Anwendung zur Verfügung gestellt werden können. Damit diese mit der Aussenwelt kommunizieren können, stellen sie Schnittstellen zur Verfügung, auch Endpoints genannt. Ein Client kann einen solchen Endpoint dann nutzen, um Nachrichten an den Service zu senden. Ausserdem kann er seinerseits wiederum Endpoints bereitstellen, so dass der Service wiederum Nachrichten an den Client senden kann.
Prinzipiell unterstützt die Windows Communication Foundation Kommunikation sowohl im Halb- wie auch im Vollduplexbetrieb. Während es zu einem Service zunächst weiter nicht viel zu sagen gibt, stellen Endpoints ein interessantes Konstrukt dar, da sie für die direkte Kommunikation verantwortlich sind. Damit ein Client mit einem Service über einen Endpoint Kontakt aufnehmen kann, muss er drei Eigenschaften über diesen wissen: die Adresse, das Binding und den Contract. Alle drei werden in .Net 3.0 in der Klasse ServiceEndpoint bereitgestellt.
Die Adresse bestimmt zunächst, wo sich der Endpoint befindet. Daher besteht eine Adresse im wesentlichen aus einer URI, welche die Lokation des Endpoints bestimmt. Neben der URI enthält die Addresse (definiert über die Klasse EndpointAddress) noch eine Identität sowie weitere, optionale Header, welche die Adresse näher beschreiben können.
Nachdem festgelegt ist, wo sich ein Endpoint befindet, wird über das Binding bestimmt, wie dieser mit der Aussenwelt kommuniziert. Zu den hier definierten Eigenschaften gehören beispielsweise das Protokoll (HTTP, SMTP etc.), das Encoding der zu übertragenden Nachrichten (Plain Text, XML usw.) und die zu verwendenden Sicherheitsrichtlinien (z.B. SSL). All dies wird über die Klasse Binding bereitgestellt, die dem Binding zudem noch einen
Namen sowie einen Namensraum zuordnet.
Mit der Adresse und dem Binding ist es möglich, einen Endpoint anzusprechen – lediglich die Frage, welche Daten eigentlich übertragen werden sollen, ist noch offen. Genau dafür gibt es den Contract, der die einzelnen Methoden des Services beschreibt. Die Klasse ContractDescription enthält ebenfalls einen Namen und einen Namensraum, die den Contract eindeutig identifizieren, sowie eine Reihe von OperationDescriptions, welche die Methoden eines Services beschreiben. Die ContractDescription wird in .Net als einfache Schnittstelle implementiert, die mit speziellen Attributen als ContractDescription gekennzeichnet wird. Der eigentliche Service muss dann diese Schnittstelle implementieren (Codekasten 1).
Der interessante Aspekt bei der Windows Communication Foundation ist nun, dass sich beispielsweise Bindings im nachhinein austauschen lassen und sich die Kommunikation zwischen zwei Services durch Änderung der entsprechenden Konfigurationsdateien zum Beispiel von HTTP auf SMTP umstellen lässt – ohne, dass auch nur eine Zeile Code geändert oder die Applikation
gar neu kompiliert werden
muss.
Was noch bleibt, ist die Frage, wo ein entsprechender Windows Communication Foundation Service «lebt». So wie ein Web Service zur Ausführung beispielsweise den IIS benötigt oder der SQL Server 2005 für Code als Host dienen kann, benötigen auch WCF-Services einen Host. Dieser wird durch die Klasse ServiceHost bereitgestellt und stellt die Server-Endpoints für die zugehörigen Services mit den konfigurierten Daten zur Verfügung. Die Endpoints werden dabei in einer XML-Datei konfiguriert.
Damit Clients dann auf diese Services zugreifen können, müssen sie lediglich eine Verbindung zu diesem ServiceHost aufnehmen, und schon können Nachrichten ausgetauscht werden (Codekasten 3). Das Umwandeln der Nachrichten in das richtige Format, das Formatieren, das eventuell nötige Ver- und Entschlüsseln, dies alles wird für den Entwickler transparent im Hintergrund von der Windows Communication Foundation erledigt.
Zur Beschreibung eines vollständigen Services einschliesslich der von ihm angebotenen Endpoints gibt es die Klasse ServiceDescription, sie enthält sozusagen alle verfügbaren Metadaten für einen Service. Diese Beschreibung kann dann ähnlich einem WSDL-Dokument von einem Server angeboten werden, damit Clients einen Überblick über die verfügbaren Services abrufen und diese dann einbinden können.
Auf der Clientseite gibt es ein entsprechendes Gegenstück – die Klasse ChannelDescription, welche die Verbindung eines Clients zu einem Windows Communication Foundation Service, einem sogenannten Channel, repräsentiert. Im Gegensatz zur ServiceDescription, die alle von einem Server angebotenen Services enthält, beschreibt eine Instanz der ChannelDescription-Klasse nur die Verbindung eines Clients zu genau einem Endpoint, auch wenn der angesprochene Service unter Umständen weitere Endpoints anbietet. Für jede weitere Verbindung zu einem dieser Endpoints wäre wiederum eine neue ChannelDescription notwendig.
Mit der Windows Communication Foundation bietet Microsoft eine solide und vor allem konsistente Grundlage für die Kommunikation zwischen Komponenten und Applikationen in serviceorientierten Umgebungen. Insbesondere die Möglichkeit, die volatilen Eigenschaften eines Services beziehungsweise der Endpoints auch nach dem Kompilieren der Anwendung über Konfigurationsdateien ändern zu können, erleichtert die Pflege von bereits ausgeliefertem Code erheblich gegenüber klassischen Ansätzen.
Auch durch die Unabhängigkeit von konkreten technischen Implementierungen und Protokollen hat die Windows Communication Foundation gute Chancen, sehr schnell die Herzen der Entwickler zu erobern. Alles in allem – ein grosser Wurf.