Microsoft Unity, Workflow 4 and You!

I encountered an interesting challenge a few weeks ago that I didn’t get around to documenting.

At work, Workflow was never an evaluated technology and past that, best practices are hard to come by given the company’s latency in adopting new things.  Unity as an inversion of control for example, is still very rare.  I deal in WCF services mostly, and only a small group of us in my department get involved.  Unity was easy for us to “sneak” into adoption.

Now the challenge…  Workflow 4 was completely foreign to me and everyone on my team.  So we have services with mocked implementations down to the method level and we need to consume them from inside the workflow; sounds easy!

It wasn’t at first.

Not until some research revealed workflow extensions that can be added into the pipeline when executing the workflow via code.  Essentially we can create the unity container as normal, and then add the container as an extension into the workflow.  Then code activities can retreive the unity extension and use the service locator to get injected implementations.

The workflow creation and execution looked like:

        public void Execute()
        {
            IUnityContainer container = new UnityContainer();
            ProcessorUnityServiceLocator serviceLocator = new ProcessorUnityServiceLocator(container);
            ServiceLocator.SetLocatorProvider(() => serviceLocator);

            ActualWorkFlowXaml flow = new ActualWorkFlowXaml();
            WorkflowApplication app = new WorkflowApplication(flow);

            // add the service locator to the WF version of a service locator
           app.Extensions.Add<IServiceLocator>(() => serviceLocator);

            app.Run();
        }

Which is nice and clean…   all the Unity bindings are already done before this clearly.

And in a new base code activity inheriting CodeActivity you pull it out:

        protected BaseUnityServiceLocator ServiceLocator { getset; }

        // If your activity returns a value, derive from CodeActivity<TResult>
        // and return the value from the Execute method.
       protected override void Execute(CodeActivityContext context)
        {
            ServiceLocator = (BaseUnityServiceLocator)context.GetExtension<IServiceLocator>();
        }

Enjoy, if I missed anything, post back, I’ll try to answer any questions.

Advertisements