Passing Values between Workflow Activities
It’s been a long while but in the old WF 3.5 days as I recall there was this funky binding thing that allowed you to pass values from the output of one activity directly to the input of another activity. Windows Workflow Foundation (WF4) does not work this way. This is obvious to people who have been using it for a while but there are a whole bunch of developers who are just now getting to work with WF4 for the first time and recently one of them asked me how they can pass values between activities so I cooked up a quick sample application for them.
Here you see a Sequence with a Source and a Destination activity. Suppose I want to pass a value from SourceActivity to DestActivity how do I do it?
First the code
SourceActivity has an OutArgument<string> that will hold the value we want to pass into DestActivity
public sealed class SourceActivity : CodeActivity
{
public InArgument<string> Text { get; set; }
public OutArgument<string> MyOutArg { get; set; }
protected override void Execute(CodeActivityContext context)
{
MyOutArg.Set(context, "The text is " + Text.Get(context) );
}
}
DestActivity has an InArgument<string> that we want to use to receive the value passed out of SourceActivity
public sealed class DestActivity : CodeActivity<String>
{
public InArgument<string> Text { get; set; }
protected override string Execute(CodeActivityContext context)
{
return "Destination received: " + Text.Get(context);
}
}
Step 1: Declare a variable
Any time you want to receive a value passed via an OutArgument<T> you must declare a variable of the correct type.
Here you can see I declared a variable of type string named MyVariable.
Step 2: Set the value of the Source OutArgument<T> to the variable
I never really thought about it until today but it does seem a little strange that to put a value into MyVariable I have to set it as the value for the OutArgument property, but that is how it is done. Just click on the SourceActivity and set the property
Step 3: Set the value of the Destination InArgument<T> to the variable
It’s that simple
Just remember that variables have lifetime and scoping rules in WF so the variable must be declared at the correct scope. Some people who are building design experiences for non-developers felt that trying to teach people the concepts of variables and types was too much so they automatically generate variables and wire up the arguments which is a nice technique to simplify the process when re-hosting the designer.
Happy Coding!
Ron Jacobs
https://blogs.msdn.com/rjacobs
Twitter: @ronljacobs https://twitter.com/ronljacobs
Comments
Anonymous
June 02, 2011
Thanks Ron for helping out the other day. Just a word of caution, dont define a ReadOnly attribute to out arguments. That was the reason, I wasnt able to view the argument in the property grid and hence wasnt able to bind it.Anonymous
June 03, 2011
Nice post, Ron. One thing to add here is that there is the option to use Property instead of Arguments when you want to pass values to workflow activities (the framework allows this). I researched a lot in this point, but still I could not make it work and decided to use Arguments for now. The difference between Arguments and Properties that I wanted to use is that in Properties you can restrain the input. For example, I can show a string field as a combobox, so the developer must pick one of the available values. Using Arguments, on the other hand, leaves the field open to any string. The problem trying to use Properties is that the activities cannot use the values in the Properties as expressions and I could not convert the value to a value that the activity understand. Just wanted to add the fact that the framework "allows" the use of Properties, but it isn't as trivial as I thought it would be.