Programmatically creating an Assign in a Flowchart Workflow
I need to programmatically define a serializable flowchart Windows Workflow that accepts input arguments and returns a result. I understand how to create these workflows using a designer, but I need to do it in code and have the flowchart workflow be serializable (so no lambda expressions).
I'm having trouble getting the "To" field of the Assign. The code below creates a flowchart workflow of a WriteLine followed by an Assign.
var ab = new ActivityBuilder<string> {
Name = "ActivityBuilt",
Implementation = new Flowchart {
StartNode = new FlowStep {
Action = new WriteLine { Text = new VisualBasicValue<string>("greeting") },
Next = new FlowStep {
Action = new Assign {
DisplayName = "Set result",
To = new OutArgument<string>(new VisualBasicReference<string> {
ExpressionText = "results"}),
Value = new VisualBasicValue<string>("bye")
}
}
}
}
};
ab.Properties.Add(new DynamicActivityProperty {
Name = "greeting",
Type = typeof (InArgument<string>),
Value = "hello"});
ab.Properties.Add(new DynamicActivityProperty {
Name = "results",
Type = typeof (OutArgument<string>),
Value = "bye"});
// Convert the ActivityBuilder to a callable activity
using (var sw = new StringWriter()) {
using (var xw = ActivityXamlServices.CreateBuilderWriter(new XamlXmlWriter(sw, new XamlSchemaContext()))) {
XamlServices.Save(xw, LastCreated);
}
using (var sr = new StringReader(sw.ToString())) {
var wf = ActivityXamlServices.Load(sr);
return wf;
}
}
The above code fails when I try to convert from ActivityBuilder to Activity saying "Failed to create a 'OutArgument' from the text 'bye'." This works fine if I don't use the OutArgument and just pass things in.
My question is what to put in the To property? How do I reference the OutArgument I add to the ActivityBuilder.Properties? A VisualBasicReference isn't an OutArgument. Am I making this more difficult than it needs to be?
Thanks for any hints!
Edit: I want to create a workflow programmatically. The workflow needs to have input arguments and return results (output arguments).
I understand how to create the workflow and how to declare and use input arguments. I'm using an ActivityBuilder to create the workflow and to set the InArgument via the ActivityBuilder's properties. I create the workflow from 开发者_如何学Cthe ActivityBuilder by serializing to XAML and then deserializing using ActivityXamlServices.Load.
What I don't understand is how to get a result from the workflow. I assume it involves an OutArgument. How/where do I add an OutArgument to the workflow? I thought the code snippet I gave would assign a value to an OutArgument, but the call to ActivityXamlServices.Load fails with a complaint that it is unable to create the OutArgument.
- Is the approach of using ActivityBuilder correct?
- Is the "To" field of the Assign action properly referencing an OutArgument?
- How do I make the ActivityBuilder aware of the OutArgument and still be able to convert to an Activity / workflow?
Hope this clarifies my problem.
There are atleast 3 problems with the code:
- The Value of the Assign needs to be an InArgument().
- The value you are trying to read from is named "greeting" not "bye".
- The OutArgument named "results" can't have a default value.
Try the following code:
var ab = new ActivityBuilder<string>
{
Name = "ActivityBuilt",
Implementation = new Flowchart
{
StartNode = new FlowStep
{
Action = new WriteLine { Text = new VisualBasicValue<string>("greeting") },
Next = new FlowStep
{
Action = new Assign
{
DisplayName = "Set result",
To = new OutArgument<string>(new VisualBasicReference<string>
{
ExpressionText = "results"
}),
Value = new InArgument<string>(new VisualBasicValue<string>("greeting"))
}
}
}
}
};
ab.Properties.Add(new DynamicActivityProperty
{
Name = "greeting",
Type = typeof(InArgument<string>),
Value = "hello"
});
ab.Properties.Add(new DynamicActivityProperty
{
Name = "results",
Type = typeof(OutArgument<string>)
});
// Convert the ActivityBuilder to a callable activity
using (var sw = new StringWriter())
{
using (var xw = ActivityXamlServices.CreateBuilderWriter(new XamlXmlWriter(sw, new XamlSchemaContext())))
{
XamlServices.Save(xw, ab);
}
using (var sr = new StringReader(sw.ToString()))
{
var wf = ActivityXamlServices.Load(sr);
WorkflowInvoker.Invoke(wf);
}
}
精彩评论