Die thinktecture-Gespräche: Indigo
Navigation:
Seite 1 -
Seite 2 -
Seite 3
Feedback:
Sagen Sie uns, wie Ihnen unsere thinktecture-Gespräche gefallen!
CW
Ich antworte mal nicht auf alles - das ist ja ein Schwall
gewesen von Dir :)
Nein, Indigo wird nicht unattraktiv für viele Entwickler,
nur weil es nicht auf RPC setzt. Denn die Macher von Indigo sind ja keine
"Dummerle"... die haben durchaus schon einen Grund, warum Indigo mehr auf
service-orientierte Denkweise und Programmierung setzt. Und nicht so sehr auf
das herkömmliche RPC mit all seinen bekannten Unzulänglichkeiten.
Ja, das bedeutet ein "Umerziehen" und ein Umdenken
von seitens der Entwickler. Das tut weh, aber wenn der Schmerz nachlässt...
Zucker!
Wenn Du erwähnst, dass man in Indigo ja immer noch seine
Klassen mit Methoden schreibt und dies dann ja doch wieder RPC(-ähnlich)
ist, dann stimmt das so nicht. Wir müssen uns über die Ebene der Diskussion im Klaren
werden: sprechen wir über die grundlegende Art und Weise zu kommunizieren oder
über die Art und Weise, dies in Code dann auch umzusetzen?
Die Idee von Services und von Nachrichtenaustausch zwischen
Services ist ja so neu nicht, nur eben komplett anders als die enge
Kopplung, die man sich mit einem RPC-Handeln und vor allem -Denken einbrockt. Und
mit der ganzen WS-*-Geschichte auch auf hoffentlich besserem Weg als
andere, ältere Versuche.
Doch irgendwann müssen wir irgendwie auch diese Art von
Services programmieren, und dafür bedarf es eines guten, aber auch
nicht zu fremdem Programmiermodells. Mit Indigo programmierst Du nicht mehr
komplexe Objekte mit Events, Delegates etc., um mit der Außenwelt zu reden -
das kannst Du innerhalb eines Services freilich gerne weiterhin machen.
Aber nach außen hin hat dein Indigo Service eine "platte
Nachrichtensicht" als Schnittstelle. Und diese Ansicht programmierst du entweder
mit XSD & Co. oder aber eben durch Verwendung der entsprechenden Attribute
in Verbindung mit deinen als .NET Interfaces definierten Schnittstellen.
Für Cross AppDomain-Kommunikation in Indigo v1 verwendest Du
Remoting, immer. Das tust Du jetzt ja auch. Du kannst ja gar nicht explizit
auf die Cross AppDomain-Kommunikation zugreifen (also auf den
darunter liegenden Channel), das passiert einfach so. Also Remoting wie es
ursprünglich gedacht war: als internes Kommunikationsmittel ;)
RW
Ok, du trennst zwischen a. grundsätzlicher Art zu
kommunizieren und b. Notation für die Kommunikationsart im Code.
Dann stelle ich mal die Forderung auf: Eine
Kommunikationsnotation ist dann besonders passend, wenn sie die grundsätzliche
Art zu kommunizieren nicht verschleiert. Das soll nicht heißen, ich sehe jede
kleine Eigenheit einer Kommunikationsart bzw. des Mediums, aber das
grundsätzliche Kommunikationsparadigma ist erkennbar. Denn wenn ich das sehe,
kann ich mir dessen bewusst sein und an seine Chancen und Grenzen denken.
Ok?
Dann hier ein Beispiel für b. mit Indigo:
[ServiceContract]
public
interface IReservation
{
[OperationContract]
string StartReservation(string lastName, string firstName);
[OperationContract]
bool ReserveRoom(string arriveDate, string departDate, int guests);
[OperationContract]
string ConfirmReservation(bool authorize);
}
Wenn ich diese Definition eines Service sehe, was nehme ich
dann als "grundsätzliche Art der Kommunikation" an?
Es kommt mir eigentlich nur eine Stack-basierte
Kommunikation in den Sinn. Oder wenn es um verteilte Anwendungen geht, dann
eben RPC.
Du sagst, es stimme so nicht, dass Indigo "wieder
RPC(-ähnlich)" sei. Aber die obige Schnittstelle ist absolut im RPC-Stil
notiert. (Die Definition des Service als Interface halte ich an dieser Stelle
für vernachlässigbar.)
Die "'platte Nachrichtensicht'", die ein
Indigo-Service haben soll, kann ich in diesem Beispiel - entnommen dem gerade
erschienenen Buch "Programming Indigo" (http://www.microsoft.com/MSPress/books/7703.asp),
hier ein Auszug: http://msdn.microsoft.com/longhorn/default.aspx?pull=/library/en-us/dnlong/html/progindigoch5.asp
- leider nicht abgewinnen.
Für mich ist in diesem Fall meine obige Forderung nicht
erfüllt. Hm... Schade. Damit sind wir nicht wirklich einen Schritt voran
gekommen gegenüber .NET Remoting & Co. Denn - wie beim letzten Mal
ausgeführt - verschleiern die ja die grundsätzlich Stream-basierte
Kommunikation und haben damit viele Missverständnisse und Probleme
heraufbeschworen.
Wenn du also zwischen a. Ebene/Art und b. Notation
unterscheidest, dann erkläre doch bitte einmal, was denn die Ebene/Art bei
Indigo ist.
CW
Ich gebe Dir Recht.
Dein Beispiel ist auch nicht das prototypische Indigo
Service Interface wie ich es mir vorstelle. Und an diesem Buch habe ich persönlich
noch *viel mehr* auszusetzen als dieses kleine Beispielchen...
Lass mich Dein Exempel doch in zwei weiteren, abgeänderten
Varianten aufzeigen (sorry, aber ich tippe den Code in Outlook - also
kein IntelliSense und kein Compiler :)).
a) Nachrichtenorientierte .NET Typen
[ServiceContract]
public
interface IReservation
{
[OperationContract]
ReservationResponse StartReservation(ReservationRequest rr);
// andere Operationen weg gelassen - analog...
}
[DataContract]
public
class ReservationRequest
{
[DataMember(Name="LastName")]
private string lastName;
[DataMember(Name="FirstName")]
private string firstName;
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
}
b) Rohe Nachrichten
[ServiceContract]
public
interface IReservation
{
[OperationContract]
Message StartReservation(Message m);
// andere Operationen weg gelassen - analog...
}
Es handelt sich im Falle von b) um den Typen System.ServiceModel.Message.
Was ich damit sagen will: man muss auch wirklich
nachrichtenorientiert Denken und Handeln - da bin ich voll bei Dir! Sicher, am Ende des Tages wird auch die
Parameterlisten-Version in eine SOAP-Nachricht gegossen - aber es geht uns hier ja um den
*Explizitismus* des Vorgehens und Handelns!
Natürlich - und sie sind da nicht die Einzogen ;) - will
Microsoft es allen Recht machen. Ob ich das gut finde? Hm, manchmal ist etwas
mehr Radikalismus durchaus angebracht - aber ein "Weg und Pfad zurück"
ist halt für viele angenehmer und auch "finanzierbarer".
RW
Aha, aha, so ist das also: Indigo bietet also wieder mal ein
Programmiermodell, dass man eigentlich besser nicht nutzen sollte. So, so.
Microsoft möchte also wieder mal niemanden verschrecken. Das finde ich sehr
bedauerlich, sogar sehr bedenklich. Denn mit Indigo wäre die Gelegenheit
gewesen, die Fehler der DCOM- und Web Service-Zeit auszubügeln. Seit 10 Jahren
gaukelt Microsoft uns vor, RPC sei der Hit - und immer rennen die Entwickler gegen
die Wand.
Nun ist Microsoft selbst drauf gekommen, dass
nachrichtenorientierte Kommunikation in verteilter Software
"ehrlicher" ist - aber man sagt diese Wahrheit dann doch noch nicht
ganz laut.
Aber egal... Indigo ist also "unten drunter" immer
nachrichtenorientiert, d.h. es wird kein Methodenaufruf "simuliert",
sondern es werden Nachrichten von einem Kommunikationspartner zum anderen
geschickt. Wasimmer ich von meinem Partner will (Operation) und wasimmer ich
ihm dafür übergeben möchte, wird in ein Nachrichten"paket"
verschnürt. Und was er mir darauf antworten möchte (wenn überhaupt), bekomme
ich auch wieder als Paket.
Die Methodennotation mit dem Interface, die ich gebracht
habe, ist da nur "syntactic sugar" für die, die´s sozusagen
"nicht wahrhaben wollen" (oder für die ganz einfachen Fälle bzw. für
den ersten Einstieg). Letztlich wird die Signatur einer Methode immer
abgebildet auf eine Nachrichtenstruktur für die Daten, die zu einem Service
hingehen und die, die zurückkommen.
Ganz allgemein zeigt das dein Beispiel b): Ein
Indigo-Service stellt eine Operation bereit, die für eine bestimmte
Verarbeitung von Daten steht (hier: StartReservation()). Die Operation wird als
Methode eines Interface definiert. Und eine solche Operation empfängt bei "Anstoß"
ein Datenpaket als Message und retouniert ein Datenpaket als Message. Der Typ
Message ist sicherlich von Indigo vordefiniert und ist ein Sack von
Name-Wert-Paaren, oder?
Indigo ist also Microsofts Version eines Paketversenders :-)
DHL oder UPS in Software gegossen :-)
Eine Message-Datenstruktur ist aber natürlich untypisiert.
Das ist uncool. Der Trick bei RPC-style Schnittstellendefinitionen ist ja
gerade, dass ich streng typisierte Methoden definiere, die vom entfernten
Service angeboten werden. Um das auch nachrichtenorientiert zu können, gibt es
die Möglichkeit wie in deinem a) Beispiel gezeigt. Ich ersetze den
Message-Parameter (es darf wahrscheinlich nur 1 sein) und den
Message-Rückgabewert durch meine eigenen Nachrichtentypen (bei dir: ReservationRequest
und ReservationResponse).
Und diese Typen sind Klassen, weil sie Daten enthalten.
Hm... Kann man denn auch Operationen mit mehreren Messages
als Parameter definieren?
Und diese DataContract-Klassen, sollten das meine
Entitätsklassen z.B. für Person, Auftrag usw. sein? Sollte ich die am besten
gleich als DataContract-Klasse anlegen?
CW
Tja... die Fehler von DCOM & Co. wurden erkannt und
gebannt. Allerdings nicht ganz konsequent zu Ende gebracht: nämlich genau auf
Ebene des Programmiermodells. Da gebe ich Dir vollkommen Recht.
Es ist tatsächlich oftmals eine Sache des Kopfes,
nachrichtenorientiert zu arbeiten. Unten drunter ist dies freilich so, aber es muss
auch oben auf der Oberfläche *explizit* so erscheinen. Und nicht so eine
Wischi-waschi-Sache wie es jetzt ist.
Aber: ich sehe das als Chance für unsereins.
Technologievermittler und Berater sind angehalten nur die wirklich "guten und
richtigen" Portionen von indigo an den Mann zu bringen ;) Freilich tun solche
Publikationen wie das jüngst erschienene erste Indigo-Buch uns hier keinen
wirklichen Gefallen.
Es ist eine Sache der *Erziehung*. Ganz im Ernst.
"Syntactic sugar" gefällt mir sehr gut :)
Der Message-Typ ist ein CLR-Typ aus dem ServiceModel
Namespace von Indigo. Message ist eine Abbildung einer SOAP-Nachricht, als eines
SOAP Envelopes. Man muss sich allerdings nicht großartig mit SOAP auskennen.
Über die beiden Hauptbestandteile Body und Header kann man alle netten und
angenehmen Features einer SOAP-Nachricht komfortabel über den
Message-Typ anprogrammieren.
Weiters gibt es auch noch die Variante, sich eine eigene
Klasse zu schreiben, die man als Nachricht verwenden möchte. Man kann
dann mittels gewisser Attribute festlegen, welche Eigenschaften der
Klasse bspw. in den Body oder welche in den Header gehen. Und nur so Rande erwähnt: SOAP bedeutet nicht automatisch
die Verwendung von XML im Sinne von spitzen Klammern!
Für nachrichtenorientierte Programmierung gilt, dass immer
nur *ein* Parameter vom Typ System.ServiceModel.Message verwendet werden
darf. Zwar erlaubt die aktuelle Beta1-Version von Indigo auch mehrere Message-Parameter, aber dies ist einfach nur ein Bug ;) Denn
in den Metadaten (WSDL) werden diese nicht reflektiert, sondern
immer nur der erste Message-Parameter.
Ein DataContract ist exakt dies, was der Name schon
andeutet: Deine explizite Vereinbarung mit der Außenwelt, welche Daten Du in
Nachrichten verschnürt zur Verfügung stellst bzw. verarbeiten kannst. Du
musst dich *explizit* darauf einigen. Nichts geschieht (mehr - Gott sei
Dank!) "automagisch".
Navigation:
Seite 1 -
Seite 2 -
Seite 3
Feedback:
Sagen Sie uns, wie Ihnen unsere thinktecture-Gespräche gefallen!