Workflow Services in WF4

Mit der Windows Workflow Foundation 4 bekommen Entwickler die Möglichkeit schnell und einfach Workflows als WCF Dienste zu veröffentlichen. Visual Studio 2010 bringt hierzu bereits ein Projekttemplate mit, wodurch das Erstellen einer Workflow Service Anwendung mit nur wenigen Klicks realisiert werden kann.

Zwar besteht auch die Option einen WorkflowService mit einfachen Typen wie Strings, Integers usw. zu erstellen, aber im Rahmen dieses Artikels möchte ich auf den “sauberen” Weg über DataContracts eingehen.

 

Nachdem das neue Projekt vom Typ Workflow Service Application  mit Visual Studio erstellt wurde, muss eine Klasse für den DataContract hinzugefügt werden. Der Workflow in diesem Beispiel soll eine Bestellposition (bestehend aus Produktname und Bestellmenge) weiterverarbeiten und als Ergebnis die berechnete Bestellposition zurückgeben. (Bestehend aus Produktname, Bestellmenge und Gesamtpreis).

 

Der erstellte DataContract für die Eingangsnachricht (Request) sieht demnach wie folgt aus

[DataContract(
   Namespace = 
     "http://www.dotnet-rocks.de/ServiceTypes/wf4/OrderPositionRequest/2010/03/30")]
    public class OrderPositionRequest
    {
        [DataMember(IsRequired = true)]
        public String ProductName { get; set; }
        [DataMember(IsRequired = true)]
        public int OrderQuantity { get; set; }
    }

 

Das Erstellen von DataContracts ist in WCF4 unverändert im Vergleich zur Vorgängerversion WCF3. Wichtig ist lediglich dass im DataContract  Attribut der Namespace des Kontraktes angegeben wird.

Gibt man keinen Namespace für den DataContract an, findet man die altbekannte http://tempuri.org später im WSDL wieder.

Im nächsten Schritt wird der DataContract für die Ausgangsnachricht (Response) definiert

    [DataContract(
      Namespace = 
        "http://www.dotnet-rocks.de/ServiceTypes/wf4/OrderPositionRequest/2010/03/30")]
    public class OrderPositionResponse
    {
 
        public OrderPositionResponse(String productName, int orderQuantity, double totalPrice)
        {
            this.ProductName = productName;
            this.OrderQuantity = orderQuantity;
            this.TotalPrice = totalPrice;
        }
        [DataMember(IsRequired = true)]
        public String ProductName { get; set; }
        [DataMember(IsRequired = true)]
        public int OrderQuantity { get; set; }
        [DataMember]
        public double TotalPrice { get; set; }
    }

 

Beim anlegen des Projektes hat VS 2010 automatisch eine xamlx Datei angelegt, diese Datei repräsentiert den WorkflowService, der veröffentlicht werden soll. An dieser Stelle möchte ich nicht das vordefinierte Item umbenennen und anpassen, sondern von Grund auf beginnen, daher empfiehlt es sich die xamlx Datei zu löschen und über Add –> New Item–> WCF Workflow Service einen Neuen WorkflowService mit dem Namen “OrderPositionCalculationService” anzulegen.

WorkflowServices1

Ausgehend von diesem neuen WorkflowService, kann nun damit begonnen werden das BusinessRequirement abzubilden. Zunächst sollte auf der ReceiveRequest Activity einige Properties angepasst werden, damit unser späteres WSDL auch korrekt aussieht.

  • DisplayName
    • Wert: “Receive OrderPosition”
  • OperationName
    • Wert: “CalculateOrderPosition”
  • ServiceContractNamespace
    • Wert “{http://www.dotnet-rocks.de/services/wf4/}OrderPositionCalculationService”
  • CanCreateInstance
    • Wert “true”

Nachdem die Basiseinstellungen für den Empfang von Nachrichten vorgenommen wurden, muss der Activity noch gesagt werden was sie denn überhaupt empfangen bzw. verarbeiten soll. Hier kommen die Variablen der WF4 wieder ins Spiel, da der gewünschte Service eine Instanz von OrderPositionRequest verarbeiten soll, muss eine neue Variable dieses Typs zum WorkflowService hinzugefügt werden.

Bei dieser Gelegenheit, sollte die data Variable gerade gelöscht werden

Über das Variables  Tab des WorkflowDesigners kann dies sehr einfach realisiert werden.

WorkflowServices2

Den Typ der Variable kann man sehr einfach über den Type Browser festlegen wie Abbildung 3 zeigt.

WorkflowServices3

Nachdem die Variable erstellt und konfiguriert wurde, muss auf der Receive Activity noch der Message Typ festgelegt werden. Über einen Klick auf “view message” im WorkflowDesigner öffnet sich das Content Definition Fenster, hier müssen MessageData und Message Type angeben werden.

In MessageData muss die, zuvor erstellte, Variable OrderPositionToCalculate hinterlegt werden. Damit der WCF Service auch den korrekten Typ an den Workflow weitergeben kann muss auch hier nochmals der Typ der Message angegeben werden. (Abbildung 4)

WorkflowServices4

 

Analog zu Receive Activity muss nun noch die Send Response Activity konfiguriert werden. Auch hier muss zunächst eine WorkflowVariable angelegt werden. Hierbei sind folgende Einstellungen zu verwenden.

  • Name
    • Wert “CalculatedOrderPosition”
  • Variable Type
    • Wert “OrderPositionResponse”

Im Anschluss an die Variablendefinition muss auch für die Antwort der Content definiert werden. Hierbei sind die folgenden Werte anzugeben

  • Message Data
    • Wert “CalculatedOrderPosition”
  • Message Type
    • Wert “OrderPositionResponse”

An dieser Stelle ist der Rahmen des Workflow Services fertiggestellt. Nun fehlt noch die eigentliche Businesslogik. In diesem Beispiel besteht die gesamte Logik daraus, die Bestellmenge mit dem Preis des Produktes zu multiplizieren und das Ergebnis in die Variable vom Typ OrderPositionResponse zu schreiben.

Dank der BAL (Base Activity Library) der WF4, bietet die Workflow Foundation 4 auch für diese Anforderung eine einfache Lösung an, die Assign Activity.

Im WorkflowDesigner positioniert man die Assign Activity genau zwischen den Receive und Send Activities.

WorkflowServices5

Die Assign Activity kann recht einfach konfiguriert werden um die Anforderungen zu erfüllen, um den Rahmen des Artikels nicht zu sprengen, gehe ich in diesem Workflow immer von einem Produktpreis 5.95 Euro aus.

Die Assign Activity wird folgendermaßen konfiguriert

CalculatedOrderPosition = new OrderPositionResponse(OrderPositionToCalculate.ProductName, OrderPositionToCalculate.OrderQuantity, OrderPositionToCalculate.OrderQuantity * 5.95)

 

Just hit F5

Debuggen und Testen kann man seinen WorkflowService ganz einfach durch F5 oder den Befehl Debug –> Start Debugging. Visual Studio 2010 startet automatisch den WCF Test Client und hostet den zuvor erstellten Service darin. Im WCF Test Client kann man durch die Methoden des WCF-Services browsen und die gewünschte Methode invoken.

In der letzten Abbildung sieht man das Ergebnis der Arbeit, im WCF Test Client kann man die Methode CalculateOrderPosition invoken und eine Instanz des Typs OrderPositionRequest übergeben.

WorkflowServices6

Das unten dargestellte Ergebnis belegt, dass der entwickelte WorkflowService alle Anforderungen erfüllt und somit ist der erste WorkflowService auf Basis der WF4 entwickelt.

 

Technorati-Tags: ,
DotNetKicks-DE Image
Published Dienstag, 30. März 2010 22:20 von ThorstenHans
Abgelegt unter: ,

Kommentare

# Twitter Trackbacks for Workflow Services in WF4 - .NET rocks [dotnet-forum.de] on Topsy.com

Ping Antwort von  Twitter Trackbacks for                 Workflow Services in WF4 - .NET rocks         [dotnet-forum.de]        on Topsy.com

# Workflow Services in WF4

Freitag, 2. April 2010 19:34 von dotnet-kicks.de

Sie wurden gekickt (eine gute Sache) - Trackback von dotnet-kicks.de

Kommentar abgeben

(verpflichtend) 
(verpflichtend) 
(optional)
(verpflichtend)