Einstieg zur Workflow Foundation 4 : Activity selbst schreiben

by Gregor Biswanger 2. Dezember 2010 08:47

Das nächste Beispiel zeigt eine Anzahl an neuen Workflow Foundation Konzepten. Diesmal wird ein eigenes Activity erstellt, das auf Variablen zugreift und Rückgabewerte anhand von Entscheidungen erzeugt.

Beispiel: Workflow Rechner

Das Beispiel demonstriert einen Consolen-Rechner. Dazu werden die folgenden Schritte umgesetzt:

  1. Das Erstellen eines neuen Workflow Consolen-Projekts.
  2. Benutzerdefiniertes Activity erstellen.
  3. Dem Workflow ein Input und Output Argument setzen.
  4. Dem Workflow variablen setzen.
  5. Das selbst geschriebene Activity dem Workflow hinzufügen.
  6. Hinzufügen von Switch<T> und Assign Activities zum Anpassen der Rechnung.
  7. Eingabe des Anwenders aufnehmen und Workflow Host mit Parameter starten.

 

Das Erstellen eines neuen Workflow Consolen-Projekts

Dazu wird Visual Studio 2010 geöffnet und ein neues Projekt angelegt. Als Template wird unter “Workflow” – “Workflow Console Application” gewählt. Als Name wird “WorkflowRechner” verwendet.

SNAGHTML5925a4c

Abb.1 – Neues “Workflow Console Application” Projekt erzeugen.

 

Benutzerdefiniertes Activity erstellen

Für eigene Activities wird die Klasse CodeActivity von der WF (System.Activities) bereitgestellt. Dem Projekt wird eine neue Klasse mit den Namen ParseCalculatorArgs hinzugefügt. Die Klasse benötigt nur noch die CodeActivity-Klasse als Basisklasse. Somit wird von der WF erkannt das es sich um ein Activity handelt und wird nach dem Builden des Projekts auch in der Toolbox aufgelistet.

Das ParseCalculatorArgs-Activity soll die Eingabe des Anwenders auswerten und diese dementsprechend an den Workflow weitergeben. Der Workflow kann mit diesen Werten dann weiter agieren.

Für den Input (IN) von Daten zum Activity, wird ein InArgument-Type bereitgestellt. Dieses wird als Property dem Activity hinzugefügt. Die spätere Eingabe des Anwenders erfolgt in der Console als String-Wert. Das für dieses Property ein Wert existiert, ist für die Funktion des Activies ausschlaggebend. Dafür behilft das RequiredArgument-Attribute. Den mit diesen Attribute schlägt der Designer eine Validierungsnachricht das noch eine Eingabe zu diesem Feld benötigt wird. Für die komplette Dateneingabe des Anwenders wird dem Activity das Property Expression hinzugefügt.

Für die Ausgabe (OUT) der verarbeiteten Daten, wird der OutArgument-Type bereitgestellt. Auch dieser wird als Property dem selbstgeschriebenen Activity hinzugefügt. Nach der Datenverarbeitung werden die Werte als Double-Typ zurückgegeben. Daher werden zwei Properties mit FirstNumber und SecondNumber hinzugefügt.

Auch für die spätere Operation wird ein Property vom Typ String benötigt.

Die hauptsächliche Verarbeitung der Daten findet in der Execute-Methode statt. Diese wird von der Basisklasse CodeActivity bereitgestellt. Zu beginn in der Execute-Methode sollten die Out-Properties zurückgesetzt werden. Da sie für dieses Beispiel eine längere Instanz haben. Der Wert wird nicht wie gewohnt mittels “ = “-Operator zugewiesen sondern mittels Set-Methode. Der context dient zur aktuellen WF-Instanz.

Die Abfrage der Properties erfolgt mit der Get-Methode. Wobei gleich die Eingabe des Anwenders in eine String-Variable line geladen wird. Anschließend erfolgt eine Überprüfung ob vom Anwender überhaupt ein Wert existiert und dann wird die Eingabe zu einem String-Array auf gesplittet. Das String-Array wird dann den Out-Properties passend zu deren Typen zugewiesen.

 

   1:  public class ParseCalculatorArgs : CodeActivity
   2:  {
   3:      [RequiredArgument]
   4:      public InArgument<string> Expression { get; set; }
   5:      public OutArgument<double> FirstNumber { get; set; }
   6:      public OutArgument<double> SecondNumber { get; set; }
   7:      public OutArgument<string> Operation { get; set; }
   8:   
   9:      protected override void Execute(CodeActivityContext context)
  10:      {
  11:          FirstNumber.Set(context, 0);
  12:          SecondNumber.Set(context, 0);
  13:          Operation.Set(context, "error");
  14:   
  15:          string line = Expression.Get(context);
  16:              
  17:          if (!String.IsNullOrEmpty(line))
  18:          {
  19:              string[] arguments = line.Split(' ');
  20:              if (arguments.Length == 3)
  21:              {
  22:                  double number;
  23:                  if (Double.TryParse(arguments[0], out  number))
  24:                  {
  25:                      FirstNumber.Set(context, number);
  26:                  }
  27:   
  28:                  Operation.Set(context, arguments[1]);
  29:                  if (Double.TryParse(arguments[2], out number))
  30:                  {
  31:                      SecondNumber.Set(context, number);
  32:                  }
  33:              }
  34:          }
  35:       }
  36:   }

Listing 1 – Source-Code des benutzerdefinierten ParseCalculatorArgs Activity.

 

Dem Workflow ein Input und Output Argument setzen

Der Workflow bekommt nun für die Eingabe ArgExpression (string) und für die spätere Ausgabe Result (double) der verarbeiteten Daten zwei Argumente hinzugefügt.

image

Abb. 2 – Argumente für die Eingabe und Ausgabe.

 

 

Dem Workflow variablen setzen

Für die interne Verarbeitung von Prozessen dienen Variablen. Die Verwaltung ist mit den Argumenten gleichgestellt. Variablen stehen allerdings nur Activities zur Verfügung. Diese können dann für Kinder-Elemente vererbt werden. Daher wird als 1 Schritt ein Sequence Activity zum Workflow hinzugefügt. Die Sequence Activity wird ausgewählt und beim 2 Schritt zu den Variablen gewechselt. Beim 3 und letzten Schritt erfolgt dann die Deklaration der Variablen. Hier wird für eine spätere Rechenfunktion die erste Zahl, Operator und zweite Zahl benötigt. Wichtig dabei zu beachten gilt, das der Variablen-Typ für die spätere Verarbeitung richtig gesetzt wurde.

 

image

Abb. 3 – Variablen hinzufügen.

 

Das selbst geschriebene Activity dem Workflow hinzufügen

Wenn die Variablen zur Sequence Activity hinzugefügt wurden, kann das selbstgeschriebene Activity hinzugefügt werden. Dazu muss das Projekt komplett gebuildet werden [Strg] + [Shift] + [B]. Dann wird das Activity auch schon in der Toolbox zur Verfügung gestellt. Dieses wird beim 1 Schritt ganz einfach mittels Drag & Drop zur Sequence Activity hinzugefügt. Beim 2 Schritt werden die Properties vom ParseCalculatorArgs  Activity mit den Variablen zugewiesen.

 

image

Abb. 4 – ParseCalculatorArgs Activity hinzufügen und die Variablen zu den Properties zuweisen.

 

Hinzufügen von Switch<T> und Assign Activities zum Anpassen der Rechnung

Der Prozess sieht derzeit wie folgt aus: Der Anwender gibt seine Calculation ein, diese wird von der ParseCalculator Args Activity ausgewertet und nun muss zu dieser Auswertung eine Rechnung gestartet werden. Dazu sollen 4 Operatoren mit +, –, * und / unterstützt werden. Zu jeder Operation wird ein eigenständiger Code benötigt. Daher wird dem Sequence Activity ein Switch<T> Activity hinzugefügt. Beim hinzufügen wird gefragt welcher Typ für die Auswertung verwendet wird. In diesem Fall ist der Operator als String-Wert vorhanden.

 

image

Abb. 5 – Switch<T> Activity hinzufügen.

 

Dem Switch<String> Activity wird beim 1 Schritt für jeden Operator ( +, -, *, /) ein Case erzeugt. Beim 2 Schritt wird ein Assign Activity in das jeweilige Case hinzugefügt. Das Assign Activity lässt Werte innerhalb des Workflows zuweisen. Daher wird beim 3 und letzten Schritt der Variable Result ein Wert von “FirstNumber Operator LastNumber” zugewiesen.

 

image

Abb. 6 – Die Cases bekommen ein Assign Activity für die Calculation.

 

Wenn jedes Case fertig deklariert wurde, sollte es wie unter Abb.7 aussehen. Wenn keines der Operatoren vom Benutzer enthalten ist, wird der Default-Bereich ausgeführt. Dieser bekommt ein Throw Activity zur Ausnahmebehandlung.

 

image

Abb. 7 – Throw Activity wird unter Default hinzugefügt.

 

Beim Throw Activity kann dem Property Exception ein VB Code (Expression) hinterlegt werden. Hierbei wird einfach eine selbstgeschriebene Nachricht mit “Operation Invalid” weitergegeben.

 

SNAGHTML5e6e52f

Abb. 8 – Exception Message selbst definiert.

 

Dem Workflow wird der Name zu “Rechner” umbenannt. Dies wird im Properties-Window von Visual Studio geändert. Dazu darf im Designer kein Activity ausgewählt sein.

 

Eingabe des Anwenders aufnehmen und Workflow Host mit Parameter starten

Zum Ende wird in der Program.cs-Datei eine Schleife gesetzt. Diese erwartet vom Anwender eine Eingabe. Diese wird als Parameter dem Workflow zugewiesen. Anschließend wird der Workflow mit der Information gestartet. Nach der Verarbeitung wird das Ergebnis auf der Console angezeigt.

 

   1:  class Program
   2:  {
   3:      static void Main(string[] args)
   4:      {
   5:          while (true)
   6:          {
   7:              Console.Write("Rechner: ");
   8:              string expression = Console.ReadLine();
   9:   
  10:              if (!string.IsNullOrEmpty(expression))
  11:                  if (expression.Trim().ToLower() == "exit")
  12:                      return;
  13:   
  14:               Rechner rechner = new Rechner {ArgExpression = expression};
  15:   
  16:              try
  17:              {
  18:                  IDictionary<string, object> results = WorkflowInvoker.Invoke(rechner);
  19:                  Console.WriteLine("Result = {0}", results["Result"]);
  20:              }
  21:              catch (InvalidOperationException invalidOperationException)
  22:              {
  23:                  Console.WriteLine(invalidOperationException.Message);
  24:              }
  25:          }
  26:      }
  27:  }

Listing 2 – Source-Code für den Taschenrechner in der Console.

Beim starten der Anwendung kann der Anwender nun die Rechenaufgaben eingeben. Wichtig dabei ist das die Eingaben korrekt durch ein Leerzeichen getrennt eingegeben werden.

SNAGHTML5f380d1

Abb. 9 – Fertige Workflow Rechner Anwendung.



Wenn ihnen der Artikel gefallen hat oder er für sie hilfreich war, bitten "kicken" sie ihn.
kick it on dotnet-kicks.de

Kommentare

Powered by BlogEngine.NET 1.4.5.0
Theme by Extensive SEO

Über den Autor

Gregor Biswanger

Microsoft MVP für Client App Dev
XING

Gregor Biswanger (Microsoft MVP für Client App Dev) ist freier Consultant, Trainer, Autor und Speaker.


Seine Schwerpunkte liegen im Bereich der .NET-Architektur, agilen Prozessen und XAML. Er veröffentlichte vor kurzem seine DVD´s mit Video-Trainings zum Thema „Meine erste Windows 8 App“, „Windows Store Apps mit XAML und C#“ und „WPF 4.5 und Silverlight 5“ bei Addison-Wesley von video2brain.


Biswanger ist auch im Auftrag von Intel GmbH als Technologieberater für die Intel Developer Zone aktiv und ist Leader bei der Ingolstädter .NET Developers Group (INdotNET). 

 

Video über mich:
http://www.youtube.com/watch?v=mx_6SiiLxjk


Basta! 2011 Speaker

CLIPer

MCTS
Windows SharePoint Services 3.0 – Application Development (MCTS)