locked
Generating Workflow programatically Issue RRS feed

  • Question

  • Hello Guys,

    I am generating XAML programatically. I receive a request go through that request and add each activities and variables mentioned in that request to a ActivityBuilder and at then end I Serialise ActivityBuilder and write that into a XAML file. Everything was working okay untill there was a requirement to call a external function in IF activity. I added all the required references. But I am now getting errors while generating XAML.

    Below is the funciton which I use to Iterate through DynamicActivity (which is created from serialized ActivityBuilder)

    private void InspectAndAddNewActivity(Activity root, BaseActivity baseActivity, string targetActivityId, ref List<string> activityIds, ActivityBuilder activityBuilder)
            {
                IEnumerator<Activity> activities =
                    WorkflowInspectionServices.GetActivities(root).GetEnumerator();
    
                if (root.DisplayName.ToLower().Equals(targetActivityId.ToLower()))
                {
                    activityIds = AddNewActivity(root, baseActivity);
                    return;
                }
    
                while ((activities.MoveNext()))
                {
                    InspectAndAddNewActivity(activities.Current, baseActivity, targetActivityId, ref activityIds, activityBuilder);
                }
            }
    

     And I have to call a funciton in IF activity, so I have to generate something like this (See If Activity last few lines)

    <Activity mc:Ignorable="sap" x:Class="WorkflowConsoleApplication4.Workflow1" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:f="clr-namespace:Functions;assembly=Functions" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="clr-namespace:Microsoft.VisualBasic;assembly=System" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:s1="clr-namespace:System;assembly=System" xmlns:s2="clr-namespace:System;assembly=System.Xml" xmlns:s3="clr-namespace:System;assembly=System.Core" xmlns:s4="clr-namespace:System;assembly=System.ServiceModel" xmlns:sa="clr-namespace:System.Activities;assembly=System.Activities" xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=System" xmlns:scg1="clr-namespace:System.Collections.Generic;assembly=System.ServiceModel" xmlns:scg2="clr-namespace:System.Collections.Generic;assembly=System.Core" xmlns:scg3="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:sd="clr-namespace:System.Data;assembly=System.Data" xmlns:sl="clr-namespace:System.Linq;assembly=System.Core" xmlns:st="clr-namespace:System.Text;assembly=mscorlib" xmlns:sxs="clr-namespace:System.Xml.Serialization;assembly=System.Xml" xmlns:w="clr-namespace:WorkflowConsoleApplication4" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
      <x:Members>
        <x:Property Name="argument1" Type="InOutArgument(x:String)" />
        <x:Property Name="argument2" Type="InOutArgument(sd:DataSet)" />
      </x:Members>
      <sap:VirtualizedContainerService.HintSize>526,862</sap:VirtualizedContainerService.HintSize>
      <mva:VisualBasic.Settings>Assembly references and imported namespaces for internal implementation</mva:VisualBasic.Settings>
      <Sequence sad:XamlDebuggerXmlReader.FileName="c:\users\ramk\documents\visual studio 2010\Projects\WorkflowConsoleApplication4\WorkflowConsoleApplication4\Workflow1.xaml" sap:VirtualizedContainerService.HintSize="486,822">
        <Sequence.Variables>
          <Variable x:TypeArguments="sd:DataTable" Name="dataTable" />
          <Variable x:TypeArguments="x:String" Name="commonFunctions" />
          <Variable x:TypeArguments="x:String" Default="[argument1]" Name="v_argument1" />
        </Sequence.Variables>
        <sap:WorkflowViewStateService.ViewState>
          <scg3:Dictionary x:TypeArguments="x:String, x:Object">
            <x:Boolean x:Key="IsExpanded">True</x:Boolean>
          </scg3:Dictionary>
        </sap:WorkflowViewStateService.ViewState>
            <If Condition="[Testing.Functions.CommonFunctions.Evaluate(argument1)]" sap:VirtualizedContainerService.HintSize="464,206" />
      </Sequence>
    </Activity>
    

    Now when I am Iterating through activity list this gives runtime error saying that "argument1" and "Testing" is not accessible.

    But when I copies same xaml (extracted while generating it, while debugugging) to a XAML file it still complains about same thing, but when I closes that xaml file once and open that again, it works fine.

    So it seems that this is generating right XAML but not sure why it fails then at runtime.

    Please advice.

    Let me know If you wnat more information.

    regards,

     


    Software Engineer
    Sunday, January 22, 2012 8:37 PM

Answers

  • Hi Ram,
    I belive the problem is because you are effectively iterating over only part of the workflow (or the workflow implementation without its ActivityBuilder information), instead of a complete workflow including argument definitions. The problem arises from a couple factors:

    Factor 1 - WorkflowInspectionServices doesn't understand ActivityBuilders and the properties collection on it, so when you use it to walk the implementation of your ActivityBuilder it would be as if the arguments were not declared.

    Factor 2 - WorkflowInspectionServices also works based on cached metadata and if you CacheMetadata on a non-root activity, then it is as if that activity is the root of the workflow.

    Factor 3 - WorkflowInspectionServices performs workflow validation simultaneously with walking through the workflow tree with GetActivities(), so it validates even when you don't really need it as in this scenario

    Serializing to xaml and reloading as fresh DynamicActivity object before doing the tree walk should be a reliable option. There might be something more performant than that, but right now I don't know enough about how you can recache metadata safely to make a recommendation.
    Tim

    Thursday, January 26, 2012 5:18 AM

All replies

  • Hi Ram,
    I belive the problem is because you are effectively iterating over only part of the workflow (or the workflow implementation without its ActivityBuilder information), instead of a complete workflow including argument definitions. The problem arises from a couple factors:

    Factor 1 - WorkflowInspectionServices doesn't understand ActivityBuilders and the properties collection on it, so when you use it to walk the implementation of your ActivityBuilder it would be as if the arguments were not declared.

    Factor 2 - WorkflowInspectionServices also works based on cached metadata and if you CacheMetadata on a non-root activity, then it is as if that activity is the root of the workflow.

    Factor 3 - WorkflowInspectionServices performs workflow validation simultaneously with walking through the workflow tree with GetActivities(), so it validates even when you don't really need it as in this scenario

    Serializing to xaml and reloading as fresh DynamicActivity object before doing the tree walk should be a reliable option. There might be something more performant than that, but right now I don't know enough about how you can recache metadata safely to make a recommendation.
    Tim

    Thursday, January 26, 2012 5:18 AM
  • Thanks Tim,

    Yours answer helped.

     

    regards,

     


    Software Engineer
    Friday, January 27, 2012 9:03 PM