2010-12-02 48 views
2

Comment puis-je définir de façon dynamique les valeurs de variables à partir de la portée parente dans une activité Windows Workflow Foundation sous .NET 4?Définition dynamique de variables dans la portée externe à partir de l'activité WF 4

Une tentative qui a échoué (baisse une activité de séquence sur un flux de travail où la séquence a une variable int nommée Test):

public sealed class CodeActivity1 : NativeActivity 
{ 
    protected override void CacheMetadata(NativeActivityMetadata metadata) 
    { 
     _locationReferences = 
      metadata.Environment.GetLocationReferences().ToList(); 

     base.CacheMetadata(metadata); 
    } 

    protected override void Execute(NativeActivityContext context) 
    { 
     LocationReference locationReference = 
      _locationReferences.Find(
       x => x.Name == "Test" && x.Type == typeof (int)); 

     if (locationReference != null) 
     { 
      Console.WriteLine(
       locationReference.Name + " " + locationReference.Type); 

      // Blows up here. 
      Location location = locationReference.GetLocation(context); 
      location.Value = 5; 
     } 
    } 

    private List<LocationReference> _locationReferences; 
} 

Il en résulte:

System.InvalidOperationException était non gérée par le code utilisateur
Message = Activité '1.2: CodeActivity1' ne peut pas accéder à cette variable car est déclarée au champ d'activité '1.1: Séquence'. Une activité peut uniquement accéder à ses propres variables d'implémentation .

Il ne trouve la variable; il ne peut tout simplement pas obtenir ou définir sa valeur.

Le nom de la variable ("Test" dans l'exemple ci-dessus) ne serait pas connu avant l'exécution.

Répondre

6

La manière normale de traiter cela est de définir un OutArgument et dans le concepteur de workflow lier la OutArgument à votre variable. Dans l'activité, vous travaillez uniquement avec l'argument. Utiliser une NativeActivity vous donne un OutArgument nommé Result mais ajouter une propriété de OUtArgument suffira.

Un autre avantage est que vous n'avez pas besoin de connaître les noms des variables « magiques » pour stocker les résultats dans.

mise à jour, car le code dans le commentaire ci-dessous est illisible.

Essayez d'ajouter ce qui suit juste avant la ligne, il explose:

var pi = context.GetType().GetProperty("AllowChainedEnvironmentAccess", BindingFlags.NonPublic | BindingFlags.Instance); 
pi.SetValue(context, true, null); 

utiliser totalement pas pris en charge avec soin si :-)

+0

J'ai une exigence que les clients ne disposent pas de connaissances de hardcoded le flux de travail. Nous sommes habitués aux BPM où vous pouvez créer un processus en transmettant des noms, des paires de valeurs pour initialiser les champs, interroger un processus en cours pour obtenir une liste de champs puis les définir, etc. Il est plus flexible, découvrable et découplé le coût de la sécurité d'exécution. Passer d'un BPM à WF revient à passer d'un langage typé dynamiquement à un langage typé statiquement. Je pense que nous avons deux options: truquer avec une variable de type Dictionary ou interroger le WSDL. – TrueWill

+0

Je pense que j'ai complètement mal compris votre question. J'avais l'impression que vous essayez d'utiliser des variables de flux de travail spécifiques et que cela n'a rien à voir avec les clients WSDL et WCF. Les paramètres de requête WCF sont uniquement le résultat des paramètres de réception. La manière dont vous liez le résultat aux variables de flux de travail internes, ou même ignorez la valeur, est complètement transparente pour l'application cliente. – Maurice

+0

@Maurice - J'ai essayé de garder l'exemple simple. Je voulais que le paramètre Receive soit un type fixe, avec une collection de noms, de paires de valeurs. Lorsqu'il est appelé, il met à jour dynamiquement toutes les variables de portée dont les noms correspondent. – TrueWill