Динамическая установка переменных во внешней области действия WF 4 - PullRequest
2 голосов
/ 03 декабря 2010

Как я могу динамически установить значения переменных из родительской области в действии Windows Workflow Foundation в .NET 4?

Неудачная попытка (сброс действия Sequence в рабочем процессе, где в Sequence есть переменная int с именем 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;
}

В результате:

System.InvalidOperationException было не обрабатывается кодом пользователя
Сообщение = действие '1.2: CodeActivity1' не может получить доступ к этой переменной, потому что она декларируется по сфере деятельности «1.1: Последовательность». Деятельность может только получить доступ к собственной реализации переменные.

Он находит переменную; он просто не может получить или установить его значение.

Имя переменной («Тест» в приведенном выше примере) не будет известно до времени выполнения.

1 Ответ

6 голосов
/ 03 декабря 2010

Обычный способ справиться с этим - определить OutArgument и в конструкторе рабочих процессов связать OutArgument с вашей переменной. В упражнении вы работаете только с аргументом. Использование NativeActivity дает вам OutArgument с именем Result, но просто добавление свойства OUtArgument подойдет.

Еще одним преимуществом является то, что вам не нужно знать «волшебные» имена переменных для хранения результатов.

Обновление, поскольку код в комментарии ниже не читается.

Попробуйте добавить следующее прямо перед строкой, в которой оно взрывается:

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

Полностью не поддерживается, поэтому используйте с осторожностью: -)

...