(WF4.5) Using CSharpValue<T> and CSharpReference<T> in .Net 4.5 – Compiling expressions–and changes in Visual Studio generated XAML

I’ve been publicizing for a while that Visual Studio 11 (still in Beta) supports C# expressions in workflow designer. Of course you might also possibly want to use C# or VB expressions by writing a workflow in code, instead of by building it in Visual Studio. There are actually a couple tricks to doing this, so that is today’s topic – how to!

Recently we looked at the WF XAML which is produced by Visual Studio 2010, and noticed that it had a couple things in there specifically for the Visual Basic compiler to understand namespaces and assembly references for Visual Basic expressions.

Today, if we look at the WF XAML which is produced by Visual Studio 2011 for a C# .Net 4.5 project, we’ll see that it is quite different!

Here is a hello world example, and I will highlight the keywords that deserve discussion today.

<Activity mc:Ignorable="sap sap2010 sads" x:Class="WorkflowConsoleApplication1.Workflow1" 
  <x:Property Name="user" Type="InArgument(x:String)" />
    <sco:Collection x:TypeArguments="x:String">
    <sco:Collection x:TypeArguments="AssemblyReference">
<WriteLine sap2010:WorkflowViewState.IdRef="WriteLine_1">
  <InArgument x:TypeArguments="x:String">
    <mca:CSharpValue x:TypeArguments="x:String">"Hello! " + user</mca:CSharpValue>
      <sap2010:ViewStateData Id="WriteLine_1" sap:VirtualizedContainerService.HintSize="211,59" />
      <sap2010:ViewStateData Id="WorkflowConsoleApplication1.Workflow1_1" sap:VirtualizedContainerService.HintSize="251,139" />


Now, for the key to the above diagram, explaining each interesting piece.


This is a new XAML attached property to indicate to Visual Studio that the workflow was created as a  C# workflow, and that all expressions inside of the workflow are C# expressions. It can appear either as an XML attribute or an XML element, depending on how the XAML was generated.


This is the new, more explicit way of representing the namespaces you’ve imported in the ‘Imports’ control which pops up at the bottom of the designer. The reason this has changed is because it actually fixes some bugs in the WF4 approach of automatically deriving your imported expression namespaces based on xmlns references, which we used for VB expressions in .Net 4 workflows.


<TextExpression.ReferencesForImplementation> and <AssemblyReference>

And similarly this is the new, more explicit way of representing the assemblies your workflow expressions reference, which in the past, for a workflow created in Visual Studio in .Net 4 and built using XamlBuildTask was derived from the information included in the compilation process somehow (hazy on details), and for .Net 4 XAML workflows which were loaded using XamlServices.Load() or similar, was derived from the assemblies referenced in xmlns attributes. I would imagine this also helps fix some fairly obscure bugs, but I don’t know the details.


OK, so now we understand what VS is doing, let’s see how we would do the same in a code C# workflow.

Attempt 1:

static void Main(string[] args)


    // Using DynamicActivity for this sample so that we can have an

    // InArgument, and also do everything without XAML at all

    DynamicActivity codeWorkflow = new DynamicActivity


        Name = "MyScenario.MyDynamicActivity",

        Properties =


            new DynamicActivityProperty


                Name = "user",

                Type = typeof(InArgument<string>),



        Implementation = () => new WriteLine


            Text = new CSharpValue<string>


                ExpressionText = "\"hello ! \" + user"







        new Dictionary<string, object>


            { "user", "tim" }



This looks like it should work, right? It’s just like using VBValue, right? Well…. wrong. What the? (I was rather surprised when I first saw this.)



“Expresssion Activity type ‘CSharpValue`1’ requires compilation in order to run”?? What does it mean? And why didn’t we hit this error when we ran the workflow as built using Workflow Designer in VS?

The answer is that VS cheats... in a good way! Visual Studio actually precompiles all of the C# expressions in your workflow into expression trees. And embeds those expression trees in the secret XAML resources inside your assembly which are the real way that your workflow’s implementation is loaded at runtime. This is good because your precompiled workflows run faster! But that sounds like a big problem for us, because we aren’t Visual Studio, how are we going to embed all that information in the workflow we just painstakingly wrote?

While the bad news is we have to take extra steps to compile workflows before running them, the good news is that we don’t have to precompile our workflow using VS. We can ‘precompile’ at runtime, by copy pasting a little code.

For a DynamicActivity loaded via ActivityXamlServices.Load(), you must use one of the new overloads that takes ActivityXamlServiceSettings:

DynamicActivity dynamicActivity = ActivityXamlServices.Load(s, new ActivityXamlServicesSettings{ CompileExpressions = true }); // (not yet sure when passing LocationReferenceEnvironment is required)

For a DynamicActivity not got via ActivityXamlServices.Load(), it goes like this:

static void Compile(DynamicActivity dynamicActivity)


    TextExpressionCompilerSettings settings = new TextExpressionCompilerSettings


        Activity = dynamicActivity,

        Language = "C#",

        ActivityName = dynamicActivity.Name.Split('.').Last() + "_CompiledExpressionRoot",

        ActivityNamespace = string.Join(".", dynamicActivity.Name.Split('.').Reverse().Skip(1).Reverse()),

        RootNamespace = null,

        GenerateAsPartialClass = false,

        AlwaysGenerateSource = true,



    TextExpressionCompilerResults results =

        new TextExpressionCompiler(settings).Compile();

    if (results.HasErrors)


        throw new Exception("Compilation failed.");



    ICompiledExpressionRoot compiledExpressionRoot =


            new object[] { dynamicActivity }) as ICompiledExpressionRoot;


        dynamicActivity, compiledExpressionRoot);


Now there’s a couple bits of that code which may look a little mysterious. What are ActivityName and ActivityNamespace for? And what is results.ResultType?

ActivityName and ActivityNamespace turn out to together be the name of a new type. As in System.Type, and in our case it is a dynamically generated runtime type. (Why a runtime generated type is required, I don’t yet know… but I have suspicions that it supports the compiled XAML in assembly scenario.)

Secondly, what does SetCompiledExpressionRootForImplementation do? This helper method is setting an attached property on the dynamicActivity, one which defines an instance of the type.

Now hopefully we can see what the object tree we just created looks like if we serialize out the XAML... oops! The attached property doesn’t serialize? What gives? I think this is a bug, we’ll see. Stay tuned? Smile with tongue out

Anyway that's a bit of a strange piece of code, but the good news is still that it should work - we can compile and run C# expressions in .Net 4.5.

Comments (5)

  1. Hello I am experiencing the same issue in a different flavour.

    I have this code in a concole application:


    WorkflowService wfService =


    as WorkflowService;

    Uri address = new Uri("http://localhost:1234/WorkflowService&quot;);

    WorkflowServiceHost host = new WorkflowServiceHost(wfService, address);

    // Behaviours

    host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });


    host.Description.Behaviors.Add(new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true });



    In my "BasicWFService.xamlx", I use a variable to set the content property of a SendReplyToRecieve shape.

    As far as I am concernet this refers to the XAMLX section:

    <SendReply Request="{x:Reference __ReferenceID0}" DisplayName="SendReplyToReceive" sap2010:WorkflowViewState.IdRef="SendReply_2">

           <SendMessageContent DeclaredMessageType="x:String">

            <p1:InArgument x:TypeArguments="x:String">

               <mca:CSharpValue x:TypeArguments="x:String">extensionResultVariable</mca:CSharpValue>




    I use the VS2011 WcfTestClient to call the service and execute the workflow.

    I get the following error in the WcfTestClient consolle, instead of receiving the response message from the workflow execution (see ScreenShot.jpg file):

    Expression Activity type 'CSharpValue`1' requires compilation in order to run. Please ensure that the workflow has been compiled.


  2. tilovell09 says:

    Hi Cinnio,

    I think you can do the same procedure for compiling your WorkflowService, but

    -probably you need to target it upon WorkflowService.Body

    -probably you need to call SetCompiledExpressionRoot instead of SetCompiledExpressionRootForImplementation


  3. tilovell09 says:

    I have tried this out, and for people who want to compile expressions from XAMLX for WorkflowServiceHost, there are actually THREE changes to the code in this article. They are:

    1) target WorkflowService.Body  (which is type Activity)

    2) call SetCompiledExpresssionRoot (instead of SetCompiledExpressionRootImplementation)

    3) in TextExpressionCompilerSettings you must set *ForImplementation = false*.

    ForImplementation = true is for compiling expression on ActivityBuilders or DynamicActivities only, it should not be true for compiling a XAMLX activity.

    (If you're using WorkflowServiceHost and not using a XAMLX file, but instead are newing up a specific custom activity type from an ActivityLibrary you shouldn't hit any of these problems with precompilation, since ActivityLibrary activities are precompiled already when they are added as part of the assembly.)

  4. Torben Rahbek Koch says:

    MSDN Documentation for compiling the C# expressions:


    Note that there are some esoteric scenarios where even this, does not work.

  5. Ilya says:

    But what if I get an activity directly from WorkflowDesigner. How can I set CompileExpressions property?

Skip to main content