Деятельность не может установить переменную, определенную в ее области? - PullRequest
3 голосов
/ 09 июня 2011

Этот заставляет меня почесать голову, и мне интересно, правильно ли я это понимаю.

Я пытаюсь определить переменную внутри действия, которая может использоваться дочерними действиями. Родитель должен иметь возможность установить значение в этой переменной во время выполнения.

Вот урезанный родительский класс:

public sealed class Parent : NativeActivity, IActivityTemplateFactory
{
    public Collection<Child> Children { get; private set; }
    private CompletionCallback<string> _cc;
    private Variable<int> _index;
    public Collection<Variable> Variables { get; private set; }        
    public Parent()
    {
        Children = new Collection<Child>();
        _index = new Variable<int>();
        _cc = new CompletionCallback<string>(OnComplete);
        Variables = new Collection<Variable>();
    }
    protected override void CacheMetadata(NativeActivityMetadata metadata)
    {
        base.CacheMetadata(metadata);
        metadata.AddImplementationVariable(_index);
        metadata.SetVariablesCollection(Variables);
    }
    protected override void Execute(NativeActivityContext context)
    {
        _index.Set(context, 0);
        var input = Variables.First(x => x.Name == "ThisIsTheVariable");
        input.Set(context, "This is the Value");
        context.ScheduleActivity(Children[0], _cc);
    }
    private void OnComplete(NativeActivityContext context, ActivityInstance instance, string result)
    {
        var index = _index.Get(context) + 1;
        _index.Set(context, index);
        Console.WriteLine(result);
        if (index < Children.Count)
            context.ScheduleActivity(Children[index], _cc);
    }
    Activity IActivityTemplateFactory.Create(System.Windows.DependencyObject target)
    {
        var retval = new Parent();
        retval.Variables.Add(new Variable<string>("ThisIsTheVariable"));
        return retval;
    }
}

Теперь, если я добавлю это в рабочий процесс и запущу его, я получу следующее крайне ироничное исключение:

Операция "1.1: Родитель" не может получить доступ эта переменная, потому что она объявлена по сфере деятельности '1.1: Родитель». Деятельность может получить доступ только к свои собственные переменные реализации.

Проблема в том, что мне нужно передать значение моему ребенку, с которым он может связываться во время разработки. Это означает, что все, что имеет значение, должно быть видно в значении дочерних операций. Единственный способ сделать это - определить переменную, как описано выше, или создать OutArgument на родительском объекте. Второй вариант безрезультатный отстой.

Как мне обойти это?


Редактировать

Пытался немного обмануть переменную, которая не работала.

Я объявил переменную в моем Parent:

// declaration
private Variable<string> _text;

// in ctor I create it
_text = new Variable<string>(InputName);

// in CacheMetadata I declare it an implementation variable
metadata.AddImplementationVariable(_text);

// in IActivityTemplateFactory.Create I add it to Variables
var retval = new Parent()
{
    Input = new InArgument<string>()
};
retval.Variables.Add(retval._text);
return retval;

Это работает до времени исполнения. Переменная появляется в области дизайна, и мои дочерние действия могут связываться с ней. Но я все еще не могу коснуться этого во время выполнения. Я могу попытаться сделать это двумя способами:

// set text via the implementation variable
protected override void Execute(NativeActivityContext context)
{
    _text.Set(context, "DERP");
    context.ScheduleActivity(Children[0], _cc);
}

Это не выбрасывает, но дочерние действия никогда не видят DERP, так как экземпляр переменной, с которой они связаны, по-видимому, не совпадает с _text, поскольку привязка оценивается как null.

Второй способ - извлечь переменную из коллекции Variables и установить ее.

protected override void Execute(NativeActivityContext context)
{
    Variables.First().Set(context, "DERP");
    context.ScheduleActivity(Children[0], _cc);
}

Это приводит к тому же исключению. Я не могу коснуться переменной, определенной в моей области видимости.

Ответы [ 2 ]

1 голос
/ 27 сентября 2012

Старый вопрос, но так как я искал решение, возможно, кто-то еще все еще ищет ...

Я нашел способ сделать это, используя context.DataContext.

В исходном примере замените

var input = Variables.First(x => x.Name == "ThisIsTheVariable"); 
input.Set(context, "This is the Value");

с;

var input = context.DataContext.GetProperties()["ThisIsTheVariable"];
input.SetValue(context.DataContext, "This is the Value");
1 голос
/ 09 июня 2011

Вам нужно использовать ActivityAction , чтобы обернуть дочерние действия, которым нужен доступ к той же переменной, и передать их туда. Сама переменная должна быть добавлена ​​с помощью NativeActivityMetadata.AddImplementationVariable , чтобы родительское действие само могло управлять им, как вы делаете. Так поступают и такие мероприятия, как ForEach.

См. Мой блог здесь для более подробной информации.

...