Einstieg zur Workflow Foundation 4 : Workflow Extensions

by Gregor Biswanger 22. Dezember 2010 17:04

Es gibt nichts schlimmeres wie eine Anwendung oder ein Framework das nicht flexibel genug für Erweiterungen ist. Zum Glück ist es nicht so bei der Workflow Foundation 4. Denn das Framework bietet einige elegante Wege seine gewünschte Logik dazwischen zu klinken. Eines davon ist das Workflow Extension Feature. Hierbei kann eine Instanz mittels Referenzierung an Activities geleitet werden. In den meisten Fällen dient dieses Feature vor allem um den Workflow Hoster mit Events zu erweitern, die dann vom Workflow auf der Code-Ebene auslösen lässt. Das hört sich sehr kompliziert an. Keine Panik! Das folgende Beispiel zeigt „wie“ und „wann“ so etwas umgesetzt wird.

Beispiel: WorkflowExtensionExample

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 “WorkflowExtensionExample” verwendet.

SNAGHTML90d210

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

Workflow deklarieren

Folgende Schritte sollen nun dem Workflow definiert werden:

  1.  
    1. Dem Workflow ein Flowchart Activity setzen.
    2. Dem Flowchart Activity eine Variable Counter mit dem Typ int und einem Default-Wert von 0 setzen.
    3. Dem Flowchart Activity ein Assign Activity hinzufügen. Das Assign Activity soll die Variable Counter jeweils um einen Wert erhöhen (siehe Abb.2).
    4. Dem Flowchart Activity ein Delay Activity hinzufügen und dem Property Duration folgenden Wert setzen:
      TimeSpan.FromSeconds(1)
    5. Gegen Ende alle miteinander von oben nach unten Verknüpfen.

Ist alles korrekt umgesetzt worden sollte es im Designer aussehen wie unter Abb.2 veranschaulicht wird.

image

Abb. 2 – Counter Workflow

Wie beim Blog-Eintrag “Einstieg zur Workflow Foundation 4 : Activity selbst schreiben” gezeigt wurde, werden Daten immer gegen Ende eines laufenden Workflows mittels Dictionary geliefert. Nun besteht allerdings folgendes Szenario: Der Workflow Hoster wird innerhalb der Console gehalten und startet einen endlos laufenden Workflow.

Wie sollte man also auf die Daten vom Workflow kommen? Ganz einfach! Es wird eine Klasse mit Event und einer Methode benötigt. Das Event wird dann von der Code-Ebene abonniert. Von einem selbstgeschriebenen Activity wird dann die Methode aufgerufen die dann das Event mit Daten auslöst. Die Instanz zu dieser Klasse wird dann von der Workflow Runtime geliefert.

Für eine solche Klasse würde der Contract (Interface) wie unter Listing 1 aussehen.

   1:  public interface IWFEventExtension
   2:  {
   3:      event Action<string> SomeDataFromWF;
   4:      void SetData(string value);
   5:  }

Listing 1 – Contract für die spätere Extension-Klasse.

Dann wird eine Klasse mit dem Namen WFEventExtension angelegt, die anschließend den Contract IWFEventExtension zugewiesen bekommt. Die Methode SetData bekommt dann die Implementierung um das Event zu feuern (siehe Listing 2).

   1:  public class WFEventExtension : IWFEventExtension
   2:  {
   3:      public event Action<string> SomeDataFromWF;
   4:          
   5:      public void SetData(string value)
   6:      {
   7:          if (SomeDataFromWF != null)
   8:              SomeDataFromWF(value);
   9:      }
  10:  }

Listing 2 – Die WFEventExtension-Klasse.

In der Program.cs-Datei wird von der WFEventExtension-Klasse eine Instanz erzeugt. Dann wird das SomeDataFromWF-Event abonniert. Wenn das Event ausgelöst wird, soll in dessen Methode die Parameter auf den Bildschirm mittels Console.WriteLine ausgeben. Dann folgt eine Instanz vom WorkflowInvoker. Durch die Methode Extensions.Add kann der Workflow Runtime dann die Instanz vom WFEventExtension überreicht werden. Der Code dazu steht unter Listing 3.

   1:  class Program
   2:  {
   3:      static void Main(string[] args)
   4:      {
   5:          WFEventExtension wfEventExtension = new WFEventExtension();
   6:          wfEventExtension.SomeDataFromWF += wfEventExtension_SomeDataFromWF;
   7:   
   8:          WorkflowInvoker workflowInvoker = new WorkflowInvoker(new Workflow1());
   9:          workflowInvoker.Extensions.Add(wfEventExtension);
  10:          workflowInvoker.Invoke();
  11:   
  12:          Console.ReadLine();
  13:      }
  14:   
  15:      static void wfEventExtension_SomeDataFromWF(string value)
  16:      {
  17:          Console.WriteLine(value);
  18:      }
  19:  }

Listing 3 – Workflow Hoster mit Workflow Extension.

Jetzt wird nur noch ein selbst geschriebenes Activity benötigt, das sich die Instanz von der Workflow Runtime geben lässt.

Dazu wird eine neue Klasse mit dem Namen SetDataToSourceCode angelegt. Als Basisklasse wird die CodeActivity-Klasse verwendet. Der Wert aus dem Workflow soll anschließend über ein InArgument-Property vom Typ String folgen. Um nun auf die Extension-Instanz zu kommen wird auf die Workflow Runtime über den Parameter context.GetExtension zugegriffen. Anschließend wird die Methode SetData mit den Daten aufgerufen. Die Methode feuert später automatisch das Event auf Code-Ebene.

Der Code dazu ist unter Listing 4.

   1:  using System.Activities;
   2:   
   3:  namespace WorkflowExtensionExample
   4:  {
   5:      public class SetDataToSouceCode : CodeActivity
   6:      {
   7:          public InArgument<string> ValueFromVariable { get; set; }
   8:   
   9:          protected override void Execute(CodeActivityContext context)
  10:          {
  11:              IWFEventExtension wfEventExtension = context.GetExtension<IWFEventExtension>();
  12:              wfEventExtension.SetData(ValueFromVariable.Get(context));
  13:          }
  14:      }
  15:  }

Listing 4 – Eigenes SetDataToSourceCode-Activity das auf die Extension zugreift.

Das selbstgeschriebene Activity kann nun dem Workflow 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 unter dem Delay Activity hinzugefügt. Beim 2. Schritt werden dann nur noch die Kommunikationsrichtungen zugewiesen. Ganz wichtig ist hierbei das nach der Verarbeitung vom SetDataToSourceCode Activity das Assign Activity wieder aufgerufen wird, um eine Schleife zu bilden (siehe Abb.3).

image

Abb. 3 – Das SetDataToSourceCode Activity wird hinzugefügt.

Jetzt kann wie gewohnt die Anwendung mittels [F5]-Tastendruck ausgeführt werden.

SNAGHTML9f203f

Abb. 4 – Ausgabe des Counters.

Das Beispiel sollte nun vermittelt haben “wie” eine Workflow Extension erzeugt und bereitgestellt wird. Unter Abb.5 wird das komplette Szenario nochmals grafisch abgebildet.

image

Abb. 5 – Das Beispiel im Detail

  1. Eine Instanz der WFEventExtension wird erzeugt und das SomeDataFromWF-Event wird abonniert. Die WFEventExtension Instanz wird der Workflow Runtime mittels Extensions.Add-Methode vom WF Hoster hinzugefügt.
  2. Der Workflow läuft und ruft das SetDataToSourceCode Activity auf.
  3. Das SetDataToSourceCode Activity holt sich von der Workflow Runtime die WFEventExtension Instanz und ruft die SetData-Methode auf. Die SetData-Methode löst auf Code-Ebene das Event aus, worin die Daten vom Workflow enthalten sind.


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)