Getting Your Workflow Instance

There are a few things I feel like I should be able to do inside of a NativeActivity, but can’t - easily. Luckily, there is a way.

#1 – Resuming bookmarks – where is my workflow Instance?

You can resume a bookmark from within NativeActivity.Execute() by calling NativeActivityContext.ResumeBookmark(). But once Execute() returns, the NativeActivityContext is disposed, so you can’t use it to resume your blocking bookmark from an asynchronous operation, another thread, or an event handler.

Turns out there are other APIs which can resume bookmarks, and one of them is on WorkflowInstance or WorkflowInstanceProxy – but how does one get your WorkflowInstance?

For the first, here’s a post on WorkflowInstanceExtensions from patcarna, which is probably a better example of how to do it than I will ever write. Or you can try starting with something like the below and build on that…

#2 – Finding your workflow definition – where is my root Activity?

Again someone has decided it’s necessary to hide a lot of information, and they have made both Activity.Parent and Activity.rootInstance private… but hey, these WorkflowInstance and WorkflowInstanceProxy classes might know, right?

This seems to work:

    public sealed class GetRootActivity : NativeActivity

    {

        public class WorkflowInstanceInfo : IWorkflowInstanceExtension

        {

            public IEnumerable<object> GetAdditionalExtensions()

            {

                yield break;

            }

            public void SetInstance(WorkflowInstanceProxy instance)

            {

                this.proxy = instance;

            }

            WorkflowInstanceProxy proxy;

            public WorkflowInstanceProxy GetProxy() { return proxy; }

        }

        protected override void Execute(NativeActivityContext context)

        {

            WorkflowInstanceProxy proxy = context.GetExtension<WorkflowInstanceInfo>().GetProxy();

            Activity root = proxy.WorkflowDefinition;

           //Action resumeBookmarkLater = () => { proxy.BeginResumeBookmark(...); };

        }

        protected override void CacheMetadata(NativeActivityMetadata metadata)

        {

            base.CacheMetadata(metadata);

            metadata.AddDefaultExtensionProvider<WorkflowInstanceInfo>(() => new WorkflowInstanceInfo());

        }

    }