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.

image

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.

image

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

image

Step 3: Set the value of the Destination InArgument<T> to the variable

image

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.