具有WorkflowInvoker的输入参数的CodeActivities序列不起作用?

时间:2014-11-07 15:26:19

标签: workflow-foundation-4

如果活动在序列中,为什么不能通过WorkflowInvoker的输入字典将参数传递给CodeActivity? WorkflowInvoker.Invoke(sequence,dict)方法抛出以下异常:

  

附加信息:为根活动的参数提供的值不满足根活动的要求:

     

'Sequence':输入字典中的以下键不映射到参数,必须删除:Arg。请注意,参数名称区分大小写。


    class Program
    {
        static void Main(string[] args)
        {
            var sequence = new Sequence();
            var start = new Start();
            var end = new End();

            sequence.Activities.Add(start);
            sequence.Activities.Add(end);

            var dict = new Dictionary();
            dict["Arg"] = "Debug text.";

            WorkflowInvoker.Invoke(sequence, dict);
        }
    }

    public class Start : CodeActivity
    {
        public InArgument Arg { get; set; }

        protected override void Execute(CodeActivityContext context)
        {
            Debug.WriteLine(Arg.Get(context));
        }
    }

    public class End : CodeActivity
    {
        public InArgument Arg { get; set; } 

        protected override void Execute(CodeActivityContext context)
        {
            Debug.WriteLine(Arg.Get(context));
        }
    }

// ************** Second example with custom sequence *************************

    class Program
    {
        static void Main(string[] args)
        {
            var seq = new MySequence();
            seq.Activities.Add(new Last());
            seq.Activities.Add(new First());

            var dict = new Dictionary();
            dict["Arg"] = "Text";

            WorkflowInvoker.Invoke(seq, dict);
        }
    }

    public class First : CodeActivity
    {
        public InArgument Arg { get; set; }

        protected override void Execute(CodeActivityContext context)
        {
            var val = Arg.Get(context);
        }
    }

    public class Last : CodeActivity
    {
        public InArgument Arg { get; set; }

        protected override void Execute(CodeActivityContext context)
        {
            var val = Arg.Get(context);
        }
    }

    public class MySequence : NativeActivity
    {
        public InArgument Arg { get; set; }

        public Collection Activities = new Collection();

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

        protected override void Execute(NativeActivityContext context)
        {
            foreach (var activity in Activities)
                context.ScheduleActivity(activity);
        }
    }


1 个答案:

答案 0 :(得分:1)

代码活动从它们所在的容器中获取它们的参数而不是输入字典。容器需要有一个与字典中的参数匹配的in参数。

序列不接受参数,因此您将它们包装在Activity中 如下构造的活动是工作台

public class MyCodeWorkflow : Activity 
{
public InArgument<string> inMSG { get; set; }
public OutArgument<string> outMSG { get; set; }

public MyCodeWorkflow() 
{
    this.Implementation = () => new Sequence {
        Activities = 
        {
            new WriteLine
            {
                Text=new InArgument<string>((activityContext)=>this.inMSG.Get(activityContext))
            },

            new Assign<string>
            {
                To=new ArgumentReference<string>("outMSG"),
                Value=new InArgument<string>
                    (
                        (activityContext)=>this.inMSG.Get(activityContext)
                    )
            }
        }
    };
}
}

//host
static void Main(string[] args) 
{
     IDictionary<string, object> input = new Dictionary<string, object>();
     input.Add("inMSG","hello");
     IDictionary<string, object> output = new Dictionary<string, object>();
     MyCodeWorkflow activity = new MyCodeWorkflow();
     output = WorkflowInvoker.Invoke(activity,input);
     Console.WriteLine(output["outMSG"]);       
 }

上面的代码取自http://xhinker.com/post/WF4Authoring-WF4-using-imperative-code%28II%29.aspx