Question

am new to Windows Workflow [WF], and interested in evaluating WF for business purposes. I decided to work through an introduction

[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);
}

and encountered

Test method SomeTests.SomeTests.TestMethod threw exception: System.Activities.InvalidWorkflowException: The following errors were encountered while processing the workflow tree: 'Literal': Literal only supports value types and the immutable type System.String. The type System.IO.TextWriter cannot be used as a literal.

Poking around, I found this article describing what appears to be the error I see above.

Being new to WF, I do not really understand the change or prescribed method to work around it. So, my question is,

With WF4RC, how does one [correctly] use WriteLine activity?

Was it helpful?

Solution

Ack, k, so mental note: Attempt all permutations of a Google search. Found this after searching for

WriteLine activity WF RC

The solution is to wrap it in a 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 ());
}

which seems weird to me, but I am literally the opposite of "expert" :P

I would still welcome alternatives if anyone has them.

OTHER TIPS

just stuck over it as well ... here my humble opinion

TextWriter is an InArgument like any other element of the activity (e.g. the Text element). An InArgument is calculated in context of the workflow (so consequently uses the ActivityContext to gather the real value in this workflow).

As you assign the writer directly, it is automatically converted to an InArgument with a Literal expression behind it. Literals are more or less constant parts of a workflow and are therefore not allowed to change. The exception tells you to avoid using a type which state would change.

Using the LambdaValue expression activity allows you to assign in each instantiation of the workflow a (new) writer. The workflow expect this object to be of temporary nature till the workflow is over.

I hope this clarify this issue and I have not made myself a moroon.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top