Composite personnalisé à l'aide de NativeActivity

L’exemple CustomCompositeNativeActivity montre comment écrire une NativeActivity qui planifie d’autres objets Activity pour contrôler le flux d’exécution d’un workflow. Cet exemple utilise deux flux de contrôle communs, Sequence et While, pour illustrer cette procédure.

Détails de l'exemple

À partir de MySequence, la première chose à remarquer est qu'il dérive de NativeActivity. NativeActivity est l'objet Activity qui expose la totalité de l'exécution du workflow via le NativeActivityContext passé à la méthode Execute.

MySequence expose une collection publique d'objets Activity qui est remplie par l'auteur de workflow. Avant que le workflow ne soit exécuté, l'exécution du workflow appelle la méthode CacheMetadata sur chaque activité dans un workflow. Pendant ce processus, l'exécution établit des relations parent-enfant pour la portée des données et la gestion de la durée de vie. L’implémentation par défaut de la méthode CacheMetadata utilise la classe d’instance TypeDescriptor de l’activité MySequence pour ajouter une propriété publique de type Activity ou IEnumerable<Activity> en tant qu’enfant de l’activité MySequence.

Chaque fois qu'une activité expose une collection publique d'activités enfants, il est probable que ces activités enfants partagent l'état. Il est recommandé à l'activité parent, dans ce cas MySequence, d'exposer également une collection de variables par le biais desquelles les activités enfants peuvent y parvenir. Comme les activités enfants, la méthode CacheMetadata ajoute des propriétés publiques de type Variable ou IEnumerable<Variable> comme variables associées à l’activité MySequence.

Outre les variables publiques, manipulées par les enfants de MySequence, MySequence doit également effectuer le suivi de sa situation dans l'exécution de ses enfants. Il utilise une variable privée, currentIndex, pour ce faire. Cette variable est inscrite comme faisant partie de l’environnement MySequence en ajoutant un appel à la méthode AddImplementationVariable dans la méthode MySequence de l’activité CacheMetadata. Les objets Activity ajoutés à la collection MySequenceActivities ne peuvent pas accéder aux variables ajoutées de cette façon.

Lorsque MySequence est exécuté par l'exécution, l'exécution appelle sa méthode Execute, en lui passant un NativeActivityContext. NativeActivityContext est le proxy de l’activité dans le runtime pour le déréférencement des arguments et des variables ainsi que la planification d’autres objets Activity, ou ActivityDelegates. MySequence utilise une méthode InternalExecute pour encapsuler la logique de planification du premier enfant et tous les enfants suivants dans une méthode unique. Il commence par supprimer la référence du currentIndex. S'il est égal au nombre dans la collection Activities, la séquence est terminée, l'activité est retournée sans planifier de travail et l'exécution la déplace dans l'état Closed. Si currentIndex est inférieur au nombre d’activités, l’enfant suivant est obtenu à partir de la collection Activities et MySequence appelle ScheduleActivity, en transmettant l’enfant à planifier et un CompletionCallback qui pointe vers la méthode InternalExecute. Enfin, le currentIndex est incrémenté et le contrôle est répercuté dans l'exécution. Tant qu'une instance de MySequence a un objet Activity enfant planifié, l'exécution le considère comme étant dans l'état Exécution.

Lorsque l'activité enfant est terminée, le CompletionCallback est exécuté. La boucle continue à partir du haut. Comme Execute, un CompletionCallback prend un NativeActivityContext, en donnant à l'implémenteur l'accès à l'exécution.

MyWhile est différent de MySequence, car il planifie un seul objet Activity à plusieurs reprises et il utilise un Activity<TResult><bool> nommé Condition pour déterminer si cette planification doit avoir lieu. Comme MySequence, MyWhile utilise une méthode InternalExecute pour centraliser sa logique de planification. Il planifie le ConditionActivity<bool> avec un >boolCompletionCallback<TResult>< nommé OnEvaluationCompleted. Lorsque l’exécution de Condition est terminée, son résultat devient disponible via ce CompletionCallback dans un paramètre fortement typé nommé result. Si la valeur est true, MyWhile appelle ScheduleActivity, en transmettant l’objet BodyActivity et InternalExecute comme CompletionCallback. Lorsque l'exécution de Body est terminée, Condition est de nouveau planifié dans InternalExecute, en recommençant la boucle à zéro. Lorsque le Condition retourne la valeur false, une instance de MyWhile rend le contrôle à l'exécution sans planifier le Body et l'exécution le déplace dans l'état Closed.

Pour configurer, générer et exécuter l'exemple

  1. Ouvrez l’exemple de solution Composite.sln dans Visual Studio.

  2. Créez et exécutez la solution.