2010-02-19 6 views
5

nouveau dans Windows Workflow [WF] et intéressé par l'évaluation de WF à des fins professionnelles. J'ai décidé de travailler à travers une introductionWF4RC, l'activité WriteLine renvoie une erreur sur StringWriter affecté à TextWriter

[TestMethod] 
public void TestMethod() 
{ 
    TextWriter writer = new StringWriter(); 
    Sequence sequence = new Sequence 
    { 
     Activities = 
     { 
      // so, assigning a reference type [eg StringWriter] 
      // as target is prohibited in WF4RC. what or how do 
      // i assign a target? introduction cited above may 
      // not be current [ie may be Beta2, not RC] so ... ? 
      new WriteLine { Text = "Hello", TextWriter = writer }, 
      new WriteLine { Text = "World", TextWriter = writer } 
     } 
    }; 
    // !!! BLOWS UP !!! 
    WorkflowInvoker.Invoke (sequence); 
} 

et rencontrais

Méthode d'essai SomeTests.SomeTests.TestMethod a jeté exception: System.Activities.InvalidWorkflowException: Les erreurs suivantes ont été rencontrées lors du traitement de l'arbre de workflow: 'Literal': Literal ne prend en charge que les types de valeur et le type immuable System.String. Le type System.IO.TextWriter ne peut pas être utilisé comme littéral.

En fouillant, j'ai trouvé this article décrivant ce qui semble être l'erreur que je vois ci-dessus. Étant nouveau pour WF, je ne comprends pas vraiment le changement ou la méthode prescrite pour contourner ce problème. Donc, ma question est,

Avec WF4RC, comment utilise-t-on [correctement] l'activité WriteLine?

Répondre

8

Ack, k, so mental Remarque: Essayez toutes les permutations d'une recherche Google. Trouvé this après avoir cherché

activité WriteLine WF RC

La solution est de l'envelopper dans un LambdaValue<T>, comme ca

[TestMethod] 
public void TestMethod() 
{ 
    StringWriter writer = new StringWriter(); 
    Sequence sequence = new Sequence 
    { 
     Activities = 
     { 
      new WriteLine 
      { 
       Text = "Hello", 
       TextWriter = new LambdaValue<TextWriter> (n => writer) 
      }, 
      new WriteLine 
      { 
       Text = "World", 
       TextWriter = new LambdaValue<TextWriter> (n => writer) 
      } 
     } 
    }; 
    WorkflowInvoker.Invoke (sequence); 
    Assert. 
     AreEqual (
     "Hello\r\nWorld\r\n", 
     writer.GetStringBuilder().ToString()); 
} 

qui me semble bizarre, mais je suis littéralement le contraire de "expert": P

Je serais toujours heureux d'avoir des alternatives si quelqu'un en avait.

+0

J'ai rencontré un problème similaire en essayant de définir une chaîne []. La LambdaValue a fonctionné. Mais j'ai également remarqué que si vous utilisez InArgument cela fonctionne aussi, et c'est probablement la façon dont cela devrait être fait. – TrueEddie

0

juste coincé dessus aussi ... ici mon humble avis

TextWriter est un InArgument comme tout autre élément de l'activité (par exemple l'élément de texte). Un InArgument est calculé dans le contexte du workflow (par conséquent, utilise ActivityContext pour rassembler la valeur réelle dans ce workflow).

Lorsque vous affectez le writer directement, il est automatiquement converti en InArgument avec une expression Literal derrière lui. Les littéraux sont des parties plus ou moins constantes d'un flux de travail et ne sont donc pas autorisés à changer. L'exception vous indique d'éviter d'utiliser un type dont l'état changerait. L'utilisation de l'activité d'expression LambdaValue vous permet d'affecter dans chaque instanciation du workflow un (nouveau) rédacteur. Le workflow s'attend à ce que cet objet soit de nature temporaire jusqu'à ce que le flux de travail soit terminé. Je souhaite que cela clarifie ce problème et je ne me suis pas fait un moroon.