Erstellen von Workflows mit imperativem Code

Dieses Thema gilt für Windows Workflow Foundation 4.

Eine Workflowdefinition ist eine Struktur konfigurierter Aktivitätsobjekte. Diese Struktur mit Aktivitäten kann auf viele verschiedene Arten definiert werden, z. B. durch manuelle Bearbeitung des XAML-Codes oder mit dem Workflow-Designer, um XAML-Daten zu erzeugen. Die Verwendung von XAML ist jedoch keine Voraussetzung. Sie können Workflowdefinitionen auch programmgesteuert erstellen. Dieses Thema enthält eine Übersicht über die Erstellung von Workflowdefinitionen per Code.

Erstellen von Workflowdefinitionen

Sie können eine Workflowdefinition erstellen, indem Sie eine Instanz eines Aktivitätstyps instanziieren und die Eigenschaften des Aktivitätsobjekts konfigurieren. Für Aktivitäten, die keine untergeordneten Aktivitäten enthalten, erreichen Sie dies mit einigen Codezeilen.

Activity wf = new WriteLine
{
    Text = "Hello World."
};

WorkflowInvoker.Invoke(wf);
Ee358749.note(de-de,VS.100).gifHinweis:
In den Beispielen in diesem Thema wird WorkflowInvoker verwendet, um die Beispielworkflows auszuführen. Weitere Informationen über zum Aufrufen von Workflows, zum Übergeben von Argumenten und zu den verschiedenen verfügbaren Hostingmöglichkeiten finden Sie unter Verwenden von WorkflowInvoker und WorkflowApplication.

In diesem Beispiel wird ein Workflow erstellt, der aus einer einzelnen WriteLine-Aktivität besteht. Das Text-Argument der WriteLine-Aktivität wird festgelegt, und der Workflow wird aufgerufen. Wenn eine Aktivität untergeordnete Aktivitäten enthält, ist die Konstruktionsmethode ähnlich. Im folgenden Beispiel wird eine Sequence-Aktivität verwendet, die zwei WriteLine-Aktivitäten enthält.

Activity wf = new Sequence
{
    Activities =
    {
        new WriteLine
        {
            Text = "Hello"
        },
        new WriteLine
        {
            Text = "World."
        }
    }
};

WorkflowInvoker.Invoke(wf);

Verwenden von Objektinitialisierern

In den Beispielen in diesem Thema wird die Syntax zur Objektinitialisierung verwendet. Die Objektinitialisierungssyntax kann eine nützliche Möglichkeit zum Erstellen von Workflowdefinitionen per Code darstellen, da diese eine hierarchische Ansicht der Aktivitäten im Workflow bietet und die Beziehung zwischen den Aktivitäten anzeigt. Die Verwendung der Objektinitialisierungssyntax ist keine Anforderung der programmgesteuerten Erstellung von Workflows. Das folgende Beispiel entspricht von der Funktion her dem vorherigen Beispiel.

WriteLine hello = new WriteLine();
hello.Text = "Hello";

WriteLine world = new WriteLine();
world.Text = "World";

Sequence wf = new Sequence();
wf.Activities.Add(hello);
wf.Activities.Add(world);

WorkflowInvoker.Invoke(wf);

Weitere Informationen über zu Objektinitialisierern finden Sie unter Gewusst wie: Initialisieren von Objekten ohne Aufruf eines Konstruktors (C#-Programmierhandbuch) (möglicherweise in englischer Sprache) und Gewusst wie: Deklarieren eines Objekts mithilfe eines Objektinitialisierers (möglicherweise in englischer Sprache).

Verwenden von Variablen, literalen Werten und Ausdrücken

Achten Sie beim Erstellen einer Workflowdefinition per Code darauf, welcher Code als Teil der Erstellung einer Workflowdefinition ausgeführt wird und welcher Code als Teil der Ausführung einer Instanz dieses Workflows ausgeführt wird. Der folgende Workflow soll z. B. eine zufällige Zahl generieren und auf die Konsole schreiben.

Variable<int> n = new Variable<int>
{
    Name = "n"
};

Activity wf = new Sequence
{
    Variables = { n },
    Activities =
    {
        new Assign<int>
        {
            To = n,
            Value = new Random().Next(1, 101)
        },
        new WriteLine
        {
            Text = new InArgument<string>((env) => "The number is " + n.Get(env))
        }
    }
};

Wenn dieser Workflowdefinitionscode ausgeführt wird, erfolgt der Aufruf von Random.Next, und das Ergebnis wird in der Workflowdefinition als literaler Wert gespeichert. Es können viele Instanzen dieses Workflows aufgerufen werden, und für alle wird jeweils die gleiche Zahl angezeigt. Um die Zufallszahlengenerierung während der Workflowausführung durchführen zu lassen, müssen Sie einen Ausdruck verwenden, der bei jeder Ausführung des Workflows ausgewertet wird.

new Assign<int>
{
    To = n,
    Value = new VisualBasicValue<int>("New Random().Next(1, 101)")
}

Ein VisualBasicValue-Element stellt einen Ausdruck der Visual Basic-Syntax dar, der in einem Ausdruck als r-Wert verwendet werden kann und jedes Mal ausgewertet wird, wenn die enthaltende Aktivität ausgeführt wird. Das Ergebnis des Ausdrucks wird der Workflowvariablen n zugewiesen, und diese Ergebnisse werden von der nächsten Aktivität im Workflow verwendet. Um zur Laufzeit auf den Wert der Workflowvariablen n zuzugreifen, ist der ActivityContext erforderlich. Darauf kann mit dem folgenden Lambda-Ausdruck zugegriffen werden.

new WriteLine
{
    Text = new InArgument<string>((env) => "The number is " + n.Get(env))
}

Lambda-Ausdrücke können nicht in das XAML-Format serialisiert werden. Um diesen Ausdruck mit XAML kompatibel zu machen, verwenden Sie ExpressionServices und Convert. Dies wird im folgenden Beispiel veranschaulicht.

new WriteLine
{
    //Text = new InArgument<string>((env) => "The number is " + n.Get(env))
    Text = ExpressionServices.Convert((env) => "The number is " + n.Get(env))
}

Es kann auch ein VisualBasicValue verwendet werden.

new WriteLine
{
    //Text = new InArgument<string>((env) => "The number is " + n.Get(env))
    //Text = ExpressionServices.Convert((env) => "The number is " + n.Get(env))
    Text = new VisualBasicValue<string>("\"The number is \" + n.ToString()")
}

Weitere Informationen über zu Ausdrücken finden Sie unter Ausdrücke.

Argumente und dynamische Aktivitäten

Eine Workflowdefinition wird im Code erstellt, indem Aktivitäten in einer Aktivitätsstruktur zusammengestellt und alle Eigenschaften und Argumente konfiguriert werden. Vorhandene Argumente können gebunden werden, aber Aktivitäten können keine neuen Argumente hinzugefügt werden. Dies gilt auch für Workflowargumente, die an die Stammaktivität übergeben werden. In imperativem Code werden Workflowargumente als Eigenschaften eines neuen CLR-Typs angegeben, und in XAML werden sie mithilfe von x:Class und x:Member deklariert. Da kein neuer CLR-Typ erstellt wird, wenn eine Workflowdefinition als Struktur von Objekten im Arbeitsspeicher erstellt wird, können Argumente nicht hinzugefügt werden. Argumente können jedoch einer DynamicActivity hinzugefügt werden. In diesem Beispiel wird eine DynamicActivity erstellt, die zwei ganzzahlige Argumente verwendet, diese zusammenfügt und das Ergebnis zurückgibt. Für jedes Argument wird ein DynamicActivityProperty-Element erstellt, und das Ergebnis des Vorgangs wird dem Result-Argument von DynamicActivity zugewiesen.

InArgument<int> Operand1 = new InArgument<int>();
InArgument<int> Operand2 = new InArgument<int>();

DynamicActivity<int> wf = new DynamicActivity<int>
{
    Properties =
    {
        new DynamicActivityProperty
        {
            Name = "Operand1",
            Type = typeof(InArgument<int>),
            Value = Operand1
        },
        new DynamicActivityProperty
        {
            Name = "Operand2",
            Type = typeof(InArgument<int>),
            Value = Operand2
        }
    },

    Implementation = () => new Sequence
    {
        Activities = 
        {
            new Assign<int>
            {
                To = new ArgumentReference<int> { ArgumentName = "Result" },
                Value = new InArgument<int>((env) => Operand1.Get(env) + Operand2.Get(env))
            }
        }
    }
};

Dictionary<string, object> wfParams = new Dictionary<string, object>
{
    { "Operand1", 25 },
    { "Operand2", 15 }
};

int result = WorkflowInvoker.Invoke(wf, wfParams);
Console.WriteLine(result);

Weitere Informationen über zu dynamischen Aktivitäten finden Sie unter Erstellen einer Aktivität zur Laufzeit mit DynamicActivity.