C# – How to use workflows with older versions of activity libraries in (rehosted) workflow designer

cnetversioningworkflow-foundation

I used the rehosted workflow designer in an ASP.NET application to generate images of workflows, basically adopting the WorkflowMonitor sample in a similar way like the Atlas Workflow Monitor. Now I have started to worry about the behavior of this solution after redeployment when the installed version of the libraries no longer match the original one from old workflow definitions (especially from tracked workflows and history entries within the database that contains the XOMLs of workflows that were executed in the past). One thing worth noting is that I have read the article about using multiple versions of workflows at the same time and this is not exactly what I need as I don't really want to run the workflows with old definitions, I just want to show their diagrams. I saw just 2 solutions :

  1. Take a screenshot from the workflow designer at the time when the workflow completes / terminates, where I still have the actual version of the libraries and simply save it as a bitmap into the database.
  2. Keep older versions of libraries in a separate folder just to be able to somehow load them to the designer so that it can still generate the diagrams from old workflows even if the activities in them are no longer in the current assembly version.

As I wanted to avoid wasting space (solution 1), I decided to first try the solution 2. I have found some examples using the TypeProvider service for the WorkflowMarkupSerializer or the WorkflowDesignSurface and tried to use them. Unfortunately, in the scenario where an activity is removed in a newer library and the old library is loaded with this TypeProvider, doesn't seem to work, in case of direct use of WorkflowMarkupSerializer to read the XOML it simply excludes the missing activity from diagram, when using SqlTrackingService to load some old tracked instances it throws an exception that the type of the activity is missing (although internally it seems to use the same method of WorkflowMarkupSerializer).

Do you have some experiences with this or tips how the TypeProvider should be used what could possibly go wrong ? Thanks 😉

Best Answer

It turned out that the TypeProviders are not a reliable way to resolve assembly references that are missing for the workflow rendering (and accessing the tracking information for old activities etc.). The problem is not only that they don't work for SqlTrackingService, but also that to be able to pass an assembly into the TypeProvider it has to be loaded into the AppDomain. Having multiple versions of the same assembly in the AppDomain causes crazy things to happen, so it was absolutely necessary to avoid it.

Although it is not possible to unload an assembly from an AppDomain once it's been loaded, it is possible to create an isolated AppDomain which loads the older version of assemblies when necessary (I've done this registering to the AssemblyResolve event of the AppDomain) and then simply unload the whole AppDomain when the work is done. For example of how this can be done see related question.

Now I'm happily showing diagrams from different versions of activity libraries without any problems ;)

Related Topic