Benutzerdefinierte Zusammensetzungen mit NativeActivity
Das Beispiel CustomCompositeNativeActivity sample veranschaulicht, wie Sie eine NativeActivity schreiben, die andere Activity-Objekte einplant, um den Ablauf der Ausführung eines Workflows zu steuern. Zur Veranschaulichung dieses Vorgangs werden in diesem Beispiel zwei häufige Ablaufsteuerungen verwendet: Sequence und While.
Beispieldetails
Beginnend bei MySequence
muss als Erstes beachtet werden, dass diese von NativeActivity abgeleitet ist. NativeActivity ist das Activity-Objekt, das die volle Bandbreite der Workflowlaufzeit durch den NativeActivityContext verfügbar macht, der an die Execute
-Methode übergeben wurde.
MySequence
macht eine öffentliche Auflistung von Activity-Objekten verfügbar, die vom Workflowautor aufgefüllt werden. Bevor der Workflow ausgeführt wird, ruft die Workflowlaufzeit die CacheMetadata-Methode in jeder Aktivität in einem Workflow auf. Während dieses Prozesses legt die Laufzeit Beziehungen zwischen übergeordneten und untergeordneten Elementen für Datenbereiche und Lebensdauerverwaltung fest. Die Standardimplementierung der CacheMetadata-Methode verwendet die TypeDescriptor-Instanzklasse für die MySequence
-Aktivität, um eine beliebige öffentliche Eigenschaft des Typs Activity oder IEnumerable<Activity> als untergeordnete Elemente der MySequence
-Aktivität hinzuzufügen.
Immer dann, wenn eine Aktivität eine öffentliche Auflistung von untergeordneten Aktivitäten verfügbar macht, ist es wahrscheinlich, dass diese untergeordneten Aktivitäten ihren Zustand freigeben. Für die übergeordnete Aktivität, in diesem Fall MySequence
, besteht eine empfohlene Vorgehensweise darin, auch eine Auflistung von Variablen verfügbar zu machen, durch die die untergeordneten Aktivitäten dies erreichen können. Genau wie untergeordnete Aktivitäten fügt die CacheMetadata-Methode öffentliche Eigenschaften des Typs Variable oder IEnumerable<Variable> als Variablen, die der MySequence
-Aktivität zugewiesen sind, hinzu.
Neben den öffentlichen Variablen, die von den untergeordneten Elementen von MySequence
bearbeitet werden, muss MySequence
auch die Position aufzeichnen, an der es sich bei der Ausführung der untergeordneten Elemente befindet. Hierfür wird eine private Variable, currentIndex
, verwendet. Diese Variable wird als Teil der MySequence
-Umgebung registriert, indem der AddImplementationVariable-Methode innerhalb MySequence
-Methode der CacheMetadata-Aktivität ein Aufruf hinzugefügt wird. Die Activity-Objekte, die der MySequence
-Auflistung von Activities
hinzugefügt werden, können nicht auf Variablen zugreifen, die auf diese Weise hinzugefügt wurden.
Wenn MySequence
von der Laufzeit ausgeführt wird, ruft die Laufzeit die Execute-Methode auf und übergibt einen NativeActivityContext. NativeActivityContext ist der Proxy der Aktivität in der Laufzeit zum Dereferenzieren von Argumenten und Variablen sowie zum Planen von anderen Activity-Objekten oder ActivityDelegates
. MySequence
verwendet eine InternalExecute
-Methode zum Kapseln der Planungslogik des ersten untergeordneten Elements sowie aller nachfolgenden untergeordneten Elemente in einer einzelnen Methode. Es wird durch Dereferenzieren des currentIndex
gestartet. Wenn dieser der Anzahl in der Activities
-Auflistung entspricht, wird die Sequenz beendet, die Aktivität gibt einen Wert zurück, ohne Aufgaben zu planen, und er wird von der Laufzeit in den Zustand Closed verschoben. Wenn der currentIndex
geringer als die Anzahl von Aktivitäten ist, wird das nächste untergeordnete Element aus der Activities
-Auflistung abgerufen, und MySequence
ruft ScheduleActivity auf und übergibt das zu planende untergeordnete Element sowie einen CompletionCallback, der auf die InternalExecute
-Methode zeigt. Schließlich wird der currentIndex
inkrementiert, und die Steuerung wird zurück an die Laufzeit gegeben. Solange eine Instanz von MySequence
über ein geplantes untergeordnetes Activity-Objekt verfügt, wird diese von der Laufzeit als im ausgeführten Zustand betrachtet.
Wenn die untergeordnete Aktivität abgeschlossen wird, wird der CompletionCallback ausgeführt. Die Schleife fängt wieder von vorne an. Wie auch Execute
, verwendet ein CompletionCallback einen NativeActivityContext, sodass die Implementierung Zugriff auf die Laufzeit erhält.
MyWhile
unterscheidet sich von MySequence
dahingehend, dass es ein einzelnes Activity-Objekt wiederholt plant und einen Activity<TResult><bool> ; Wert mit dem Namen Condition
verwendet, um zu ermitteln, ob diese Planung stattfinden soll. Wie auch MySequence
, verwendet MyWhile
eine InternalExecute
-Methode, um seine Planungslogik zu zentralisieren. Es plant den Condition
Activity<bool>-Wert mit einem CompletionCallback<TResult><bool>-Wert mit dem Namen OnEvaluationCompleted
. Wenn die Ausführung von Condition
abgeschlossen ist, wird das Ergebnis durch diesen CompletionCallback in einem stark typisierten Parameter mit dem Namen result
verfügbar. Wenn true
, MyWhile
ScheduleActivity aufruft, werden das Body
Activity-Objekt und InternalExecute
als CompletionCallback übergeben. Wenn die Ausführung von Body
abgeschlossen ist, wird Condition
erneut in InternalExecute
geplant, und die Starte beginn erneut von vorne. Wenn der Condition
false
zurückgibt, gibt eine Instanz von MyWhile
die Steuerung an die Laufzeit zurück, ohne den Body
zu planen, und die Laufzeit verschiebt diesen in den Zustand Closed.
So können Sie das Beispiel einrichten, erstellen und ausführen
Öffnen Sie die Beispiellösung Composite.sln in Visual Studio.
Erstellen Sie das Projekt, und führen Sie es aus.