WF4RC, операция WriteLine выдает ошибку на StringWriter, назначенном TextWriter - PullRequest
5 голосов
/ 19 февраля 2010

Я новичок в Windows Workflow [WF] и заинтересован в оценке WF для бизнес-целей. Я решил работать через введение

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

и встретил

Метод теста SomeTests.SomeTests.TestMethod вызвал исключение: System.Activities.InvalidWorkflowException: при обработке дерева рабочих процессов возникли следующие ошибки: 'Literal': Literal поддерживает только типы значений и неизменный тип System.String. Тип System.IO.TextWriter не может использоваться как литерал.

Выискивая, я нашел эту статью , описывающую то, что кажется ошибкой, которую я вижу выше.

Будучи новичком в WF, я не совсем понимаю изменение или предписанный метод, чтобы обойти это. Итак, мой вопрос,

С WF4RC, как [правильно] использовать WriteLine активность?

Ответы [ 2 ]

8 голосов
/ 19 февраля 2010

Ack, k, поэтому помните: попробуйте все перестановки в поиске Google.Найден this после поиска

Операция WriteLine WF RC

Решение состоит в том, чтобы обернуть его в LambdaValue<T>, com 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 ());
}

, что мне кажется странным, но я буквально противоположен «эксперту»: P

Я все равно приветствовал бы альтернативы, если бы у кого-то они были.

0 голосов
/ 20 апреля 2011

просто застрял над этим ... здесь мое скромное мнение

TextWriter - это InArgument, как и любой другой элемент действия (например, элемент Text). InArgument рассчитывается в контексте рабочего процесса (следовательно, использует ActivityContext для сбора реального значения в этом рабочем процессе).

Когда вы назначаете писателя напрямую, он автоматически преобразуется в InArgument с литеральным выражением позади него. Литералы являются более или менее постоянными частями рабочего процесса и поэтому не могут меняться. Исключение говорит вам не использовать тип, состояние которого может измениться.

Использование действия выражения LambdaValue позволяет назначать в каждом экземпляре рабочего процесса (нового) средства записи. Рабочий процесс ожидает, что этот объект будет временным, пока рабочий процесс не закончится.

Я надеюсь, что это прояснит этот вопрос, и я не сделал себя дебилом.

...