Пользовательские параметры настройки деятельности для дочерней активности - PullRequest
5 голосов
/ 04 апреля 2011

Я пытаюсь создать пользовательское действие для WF4, которое содержит дочернее действие и передает некоторые аргументы его дочернему действию. Я прилагаю ниже упрощенную версию моей деятельности (Родитель и ребенок)

public class Child : CodeActivity
{
    public InArgument<Dictionary<string, object>> Data;

    protected override void Execute(CodeActivityContext context)
    {
        Dictionary<string, object> data = Data.Get(context);

        //Some operations on the input data
    }
}


 public class Parent : NativeActivity
{
    public InArgument<int> Value1 { get; set; }

    public InArgument<string> Value2 { get; set; }

    public Child Body { get; set; }


    protected override void Execute(NativeActivityContext context)
    {
        int value1 = Value1.Get(context);
        string value2 = Value2.Get(context);

        Dictionary<string, object> data = new Dictionary<string, object>();
        data.Add("value1", value1);
        data.Add("value2", value2);

        context.SetValue(Body.Data, data);

        context.ScheduleActivity(this.Body);
    }


    protected override void CacheMetadata(NativeActivityMetadata metadata)
    {
        Body = new Child();

        base.CacheMetadata(metadata);
    }
}

Аргумент Data из дочернего действия равен нулю, когда выполнение рабочего процесса достигает метода Execute для действия.

Может кто-нибудь, пожалуйста, подскажите мне, как можно передавать аргументы между этими двумя действиями?

Ответы [ 3 ]

6 голосов
/ 05 апреля 2011

В то время как подход с дополнительной переменной работает, «официальный» способ планирования дочернего элемента с некоторыми входными данными - использование в ActivityAcytion или, если вы также хотите получить результат с помощью ActivityFunc.

Боюсь, код на самом деле не станет проще и понятнее, но для полноты картины я просто решил добавить это.

public class Child : CodeActivity<object>
{
    public InArgument<Dictionary<string, object>> Data { get; set; }

    protected override object Execute(CodeActivityContext context)
    {
        Dictionary<string, object> data = Data.Get(context);

        foreach (var item in data)
        {
            Console.WriteLine(item);
        }

        return "Some result";
    }
}



public class Parent : NativeActivity<object>
{
    public InArgument<int> Value1 { get; set; }
    public InArgument<string> Value2 { get; set; }

    public ActivityFunc<Dictionary<string, object>, object> Body { get; set; }

    protected override void Execute(NativeActivityContext context)
    {
        int value1 = Value1.Get(context);
        string value2 = Value2.Get(context);

        Dictionary<string, object> data = new Dictionary<string, object>();
        data.Add("value1", value1);
        data.Add("value2", value2);

        context.ScheduleFunc<Dictionary<string, object>, object>(Body, data, ChildCompletionCallback);
    }


    protected override void CacheMetadata(NativeActivityMetadata metadata)
    {
        var arg = new DelegateInArgument<Dictionary<string, object>>();

        Body = new ActivityFunc<Dictionary<string, object>, object>
        {
            Argument = arg,
            Handler = new Child() { Data = arg }
        };

        base.CacheMetadata(metadata);
    }

    private void ChildCompletionCallback(NativeActivityContext context, ActivityInstance completedInstance, object result)
    {
        //Set the output for the parent activity at the completion of the child activity
        this.Result.Set(context, result);
    }
}
2 голосов
/ 05 апреля 2011

Мне также нужно было вернуть результат дочернего действия через родительское действие. Для этого я использовал метод ScheduleActivity с параметром CompletionCallback . Ниже я привел пример действий Parent / Child, содержащий также набор выходных аргументов, возможно, он понадобится кому-то в какое-то время:)

Родитель:

public class Parent : NativeActivity<object>
{
    public InArgument<int> Value1 { get; set; }
    public InArgument<string> Value2 { get; set; }
    private Variable<Dictionary<string, object>> SomeVariable { get; set; } // intermediate variable

    private Child Body { get; set; }

    public Parent()
    {
        this.SomeVariable = new Variable<Dictionary<string, object>>("SomeVariable");

        this.Body = new Child();
        this.Body.Data = new InArgument<Dictionary<string, object>>(SomeVariable);
    }

    protected override void Execute(NativeActivityContext context)
    {
        int value1 = Value1.Get(context);
        string value2 = Value2.Get(context);

        Dictionary<string, object> data = new Dictionary<string, object>();
        data.Add("value1", value1);
        data.Add("value2", value2);

        this.SomeVariable.Set(context, data);

        context.ScheduleActivity(this.Body, ChildCompletionCallback);
    }

    protected override void CacheMetadata(NativeActivityMetadata metadata)
    {
        base.CacheMetadata(metadata);

        // needs to be cached as implementation child and variable (Body and SomeVariable must be declared as private then)
        metadata.AddImplementationChild(this.Body);
        metadata.AddImplementationVariable(SomeVariable);
    }

    private void ChildCompletionCallback<TResult>(NativeActivityContext context, ActivityInstance completedInstance, TResult result)
    {
        //Set the output for the parent activity at the completion of the child activity
        this.Result.Set(context, result);
    }
}

Ребенок:

public class Child : CodeActivity<object>
{
    public InArgument<Dictionary<string, object>> Data { get; set; }

    protected override object Execute(CodeActivityContext context)
    {
        Dictionary<string, object> data = Data.Get(context);

        return "Some result";
    }
}
1 голос
/ 04 апреля 2011

Возможно, невозможно установить значение входного аргумента непосредственно в методе Execute.Промежуточная переменная должна быть введена.Аргумент Child.Data связан с этой переменной и в методе Parent.Execute.

Parent:

public class Parent : NativeActivity
{
    public InArgument<int> Value1 { get; set; }
    public InArgument<string> Value2 { get; set; }
    private Variable<Dictionary<string, object>> SomeVariable { get; set; } // intermediate variable

    private Child Body { get; set; }

    public Parent()
    {
        this.SomeVariable = new Variable<Dictionary<string, object>>("SomeVariable");

        this.Body = new Child();
        this.Body.Data = new InArgument<Dictionary<string, object>>(SomeVariable);
    }

    protected override void Execute(NativeActivityContext context)
    {
        int value1 = Value1.Get(context);
        string value2 = Value2.Get(context);

        Dictionary<string, object> data = new Dictionary<string, object>();
        data.Add("value1", value1);
        data.Add("value2", value2);

        this.SomeVariable.Set(context, data);

        context.ScheduleActivity(this.Body);
    }

    protected override void CacheMetadata(NativeActivityMetadata metadata)
    {
        base.CacheMetadata(metadata);

        // needs to be cached as implementation child and variable (Body and SomeVariable must be declared as private then)
        metadata.AddImplementationChild(this.Body);
        metadata.AddImplementationVariable(SomeVariable);
    }
}

Child:

public class Child : CodeActivity
{
    // Must be declared as property.
    public InArgument<Dictionary<string, object>> Data
    {
        get;
        set;
    }

    protected override void Execute(CodeActivityContext context)
    {
        var data = this.Data.Get(context);
    }
}

Это не очень хорошее решениено я не вижу ничего хорошего в WF4:).

...