none
How can I get the current workflow instance from within a NativeActivity?

    Question

  • Nothing in the context or anywhere else I look seems to have that instance.  I'm trying to see if I can find an argument on the workflow without doing the work of creating an InArgument on the activity, hooking it up in the designer, etc.  I tried this:

    var pd = context.DataContext.GetProperties().OfType<PropertyDescriptor>()
                    .Where(x=>x.PropertyType.Name == "Generator").First();


    which got me a PropertyDescriptor for the property, which is great.  But in order to get the value out, I need to do something like:

    var wf = context.DataContext.GetPropertyOwner(pd);
    var iog = pd.GetValue(wf);
    var generator = (iog as InOutArgument<Generator>).Get(context);
    of course, wf is null after the first call, but you get the general idea.

    Is this possible in beta 2?
    Friday, November 13, 2009 8:39 PM

Answers

  • Any Activity should really consume input from their InArguments only. By making sure you do this, your activity is re-usable in other workflow definitions.

    Think of an activity as a function call. It should really use only its parameters, but not global variables.

    We also understand there are scenario where you want to access some information from the "context". There is a feature called ExecutionProperty that can help you.

    Put it simply, the parent activity can set the execution property, and the child activities can consume it without declaring an argument. Even though it is possible, I don't think it is a great idea for an activity to access execution property it assume, because the execution property might not exist at all.

    There are two more things you can do, one is to expose the argument and use the execution property by default and fallback to the argument if not.
    Another thing is that you can use Validation to make sure your activity is used correctly. The GetParentChain() activity can be used to obtain all the parents and you can use validation to make sure your activity must be nested within an activity that defines the execution property.

    Here is some sample code on how you would use it.

    using System;
    using System.Linq;
    using System.Activities;
    using System.Activities.Statements;

     

        class Program
        {
            static void Main(string[] args)
            {
                WorkflowInvoker.Invoke(CreateWorkflow());
            }

            private static Activity CreateWorkflow()
            {
                return new Parent
                {
                    Child = new Child()
                };
            }
        }

        class Parent : NativeActivity
        {
            public Child Child { get; set; }

            protected override void Execute(NativeActivityContext context)
            {
                context.Properties.Add("HelloExecutionProperty", "Hello World");
                context.ScheduleActivity(this.Child);
            }
        }

        class Child : NativeActivity
        {
            protected override void Execute(NativeActivityContext context)
            {
                Console.WriteLine(context.Properties.Find("HelloExecutionProperty"));
            }
        }

    • Marked as answer by Will Sullivan Sunday, November 15, 2009 2:29 PM
    Saturday, November 14, 2009 11:35 PM

All replies

  • Are you looking for the instance to get the InstanceID?
    MS Developer Support
    Friday, November 13, 2009 10:36 PM
  • No, the instance.  As I said,

    I'm trying to see if I can find an argument on the workflow without doing the work of creating an InArgument on the activity, hooking it up in the designer, etc.

    I want the instance so I can get an argument defined on the root activity.
    Saturday, November 14, 2009 10:25 PM
  • Any Activity should really consume input from their InArguments only. By making sure you do this, your activity is re-usable in other workflow definitions.

    Think of an activity as a function call. It should really use only its parameters, but not global variables.

    We also understand there are scenario where you want to access some information from the "context". There is a feature called ExecutionProperty that can help you.

    Put it simply, the parent activity can set the execution property, and the child activities can consume it without declaring an argument. Even though it is possible, I don't think it is a great idea for an activity to access execution property it assume, because the execution property might not exist at all.

    There are two more things you can do, one is to expose the argument and use the execution property by default and fallback to the argument if not.
    Another thing is that you can use Validation to make sure your activity is used correctly. The GetParentChain() activity can be used to obtain all the parents and you can use validation to make sure your activity must be nested within an activity that defines the execution property.

    Here is some sample code on how you would use it.

    using System;
    using System.Linq;
    using System.Activities;
    using System.Activities.Statements;

     

        class Program
        {
            static void Main(string[] args)
            {
                WorkflowInvoker.Invoke(CreateWorkflow());
            }

            private static Activity CreateWorkflow()
            {
                return new Parent
                {
                    Child = new Child()
                };
            }
        }

        class Parent : NativeActivity
        {
            public Child Child { get; set; }

            protected override void Execute(NativeActivityContext context)
            {
                context.Properties.Add("HelloExecutionProperty", "Hello World");
                context.ScheduleActivity(this.Child);
            }
        }

        class Child : NativeActivity
        {
            protected override void Execute(NativeActivityContext context)
            {
                Console.WriteLine(context.Properties.Find("HelloExecutionProperty"));
            }
        }

    • Marked as answer by Will Sullivan Sunday, November 15, 2009 2:29 PM
    Saturday, November 14, 2009 11:35 PM