locked
Dynamic update of workflow activities and properties RRS feed

  • Question

  • Hi,

    I'd like to dynamically update the workflow definition of a workflow instance.
    Because I'm using WCF for communication with my workflow host (that is managing the communication with the workflow runtime) I'm doing the following:

    1. retrieve workflow definition for the workflow instance from workflow host via WCF service
    2. change the definition
    3. send the changed definition back to the workflow host via WCF service
    4. workflow host compares original with changed definition and applies the workflow changes
    (see also this thread)

    In my opinion I cannot directly use a WorkflowChanges object on the application side (step 2) because the type WorkflowChanges is not (WCF-) serializable and
    it can not be transferred to the workflow host (step 3).

    During the comparison (step 4) I also want to add activities to the original workflow that exist in the changed workflow but not  in the original one. This doesn't work and I get the following exception:
    Activity 'x' is already a child of CompositeActivity 'y'.
    StackTrace:
    at System.Workflow.ComponentModel.CompositeActivity.OnListChangingEventHandler(Object sender, ActivityCollectionChangeEventArgs e)
    at System.Workflow.ComponentModel.ActivityCollection.FireListChanging(ActivityCollectionChangeEventArgs eventArgs)
    at System.Workflow.ComponentModel.ActivityCollection.System.Collections.Generic.IList<System.Workflow.ComponentModel.Activity>.RemoveAt(Int32 index)
    at System.Workflow.ComponentModel.ActivityCollection.RemoveAt(Int32 index)
    at ..

    The same exception occurs when doing the following (same concept):

    StateMachineWorkflowActivity simpleWorkflow = new StateMachineWorkflowActivity();
    StateActivity state1 = new StateActivity("STATE_1");
    simpleWorkflow.Activities.Add(state1);
    simpleWorkflow.InitialStateName = state1.Name;

    StateMachineWorkflowActivity simpleWorkflow2 = new StateMachineWorkflowActivity();
    // throws InvalidOperationException!
    simpleWorkflow2.Activities.Add(state1);

    1. So is it not allowed to add activities that are already part of another workflow definition (or in other words: as soon as the Parent property is not null)?

    2. Then how can I accomplish this? Writing an own clone method for the activities to be added?


    Furthermore I also like to change some properties of the activities. Because this is not directly supported I use a HandleExternalEvent (with an ExternalDataExchangeService) to accomplish this. The event is triggered but I get an exception saying that "This operation can not be performed at runtime." when I try to update a property value.
    (StackTrace:
    at System.Workflow.ComponentModel.DependencyObject.SetValueCommon(DependencyProperty dependencyProperty, Object value, PropertyMetadata metadata, Boolean shouldCallSetValueOverrideIfExists)
    at System.Workflow.ComponentModel.DependencyObject.SetValue(DependencyProperty dependencyProperty, Object value)
    at System.Workflow.ComponentModel.Activity.set_Description(String value))

    The related code:

    public void HandlePropertyChangedEvent(object sender, ExternalDataEventArgs e)
    {
        PropertyEventArgs eventArgs = (PropertyEventArgs)e;
        try
        {
            Activity targetObject = GetActivityByName(eventArgs.ActivityName);
            if (targetObject != null)
            {
                PropertyInfo prop = targetObject.GetType().GetProperty(eventArgs.PropertyName);
                if (prop != null)
                {
                    prop.SetValue(targetObject, eventArgs.PropertyValue, null);
                }
            }
        }
        catch(Exception exc)
        {
        }
    }

    3. What is the reason for this exception? How can I change those values?
    (As described in [Thread 1] or [Thread 2] it should be possible to do that ..)



    4. General question: Is there any other way to do a dynamic update of a workflow definition when using a WCF service managing the workflow communication?

    Thanks for any help!


    Wednesday, June 20, 2007 8:36 AM

Answers

  • 1.     So is it not allowed to add activities that are already part of another workflow definition (or in other words: as soon as the Parent property is not null)?

    Yes, an activity can have only one parent.  If it belongs to a workflow, it cannot be added to another workflow. 

     

    2.       Then how can I accomplish this? Writing an own clone method for the activities to be added?

    If you want to added to another workflow, you need to remove it from the original workflow first.

     

    3.       What is the reason for this exception? How can I change those values?
    This is because you’re trying to change a property that’s defined as “meta” property.  There are two types of Dependency Properties, meta property and instance property.  You cannot change meta property values once the activity is initialized.  The only way to do this is to replace the original activity with an activity that has the new value for the meta property.

     

    4.       General question: Is there any other way to do a dynamic update of a workflow definition when using a WCF service managing the workflow communication?

    I think have a reasonable approach.  You can also consider developing your own grammar to define the delta between the old and the new workflow definition, serialize and send that delta across the wire through WCF and construct the WorkflowChanges class on the server side.  The advantage is depending on your implementation, the data sent across the wire might be of smaller size.

     

    Thursday, June 21, 2007 5:27 PM