19 November 2010

Assembly versioning for SharePoint Visual Studio Workflow solutions

Problem

You have a Visual Studio SharePoint sequential or state machine workflow solution deployed to your farm and have a number of active workflows. You make some changes to your workflow in development which involves some "interface" changes (e.g. you've added or removed workflow properties, states, state transitions, etc) then build, package and deploy your new workflow version to your farm. You then find that the existing active workflow instances fail (say when you try to complete a workflow task that was pending). The ULS logs show an error along the lines of:

Engine RunWorkflow: System.Workflow.Activities.EventDeliveryFailedException: Event "OnWorkflowItemChanged" on interface type "Microsoft.SharePoint.Workflow.ISharePointService" for instance id "e7903ad3-e939-4211-bf04-5efcd6bd243c" cannot be delivered. ---> System.Runtime.Serialization.SerializationException: The object with ID 250 implements the IObjectReference interface for which all dependencies cannot be resolved. The likely cause is two instances of IObjectReference that have a mutual dependency on each other

This basically implies that the persisted data for that workflow instance cannot be deserialised as it refers to the old version of the assembly interface. Put another way, existing persisted workflow data has a dependency on the existing version of your assembly DLL.

Investigation

Found lots of half answers before stumbling across this MSDN blog article by Manpreet Alag: http://blogs.msdn.com/b/malag/archive/2008/07/16/how-to-upgrade-workflow-assembly-in-moss-2007.aspx. Based on his advice I came up with the following steps to solve this problem.

Solution

The solution to this problem is two fold, so if your new workflow version contains changes to the workflow interface:

1) You MUST increment the AssemblyVersion attribute in the References.cs file of your workflow project e.g.

from:
assembly: AssemblyVersion("1.1.0.0")]

to:
[assembly: AssemblyVersion("1.2.0.0")]

Don't forget to always update the version number in the workflow.xml file within your VS project to match the new assembly version e.g.

CodeBesideAssembly="MyWF, Version=1.2.0.0, Culture=neutral, PublicKeyToken=c7fd05f7e87052db"

2) When you deploy your new version as a solution the existing assembly gets deleted from the GAC (global assembly cache in c:\windows\assembly) before adding the new one. So:

a) BEFORE you deploy your new version you must take a copy of the existing assembly from the GAC

b) deploy your new version

c) now copy the old assembly back into the GAC (drag and drop in Windows Explorer). You should now have two versions of your assembly in the GAC.

Restart IIS and restart the Windows SharePoint Services Timer service and off you go. You should test that existing workflows work/proceed correctly and that new any new workflow instances also work correctly and exhibit the behaviour desired from the new version.

Remember that you should do some housekeeping in the future to delete any old assembly versions from the GAC that no longer have any dependant workflows.