Implementing ISerializable to facilitate workflow re-hydration

I was working on a SharePoint 2007 Visual Studio Sequential Workflow. This workflow passed a proposal through layers of management for approval (pretty common workflow type task). The requirements specified that on rejecting, the workflow had to loop back around to the previous layer of management, if applicable. This requirement bumped it from a SharePoint Designer Workflow to a Visual Studio Workflow.

As I coded away, I realized it would be convenient to have a class that maintains the status of all of the levels of approval, plus have a couple methods that, when called, compile the statuses into a single, human friendly string message to facilitate easy email and log entry creations. Creating the class was elementary: private member variables to hold the data, public properties (setter and getters) to facilitate using the data and then the methods to provide the appropriately format message of concatenated information. I created the class inside my workflow project. Then had the workflow instantiate the class and make use of it. Everything was working fine and easy. Then I found the problem. Workflows dehydrate and re-hydrate. The concept of “hydration” is the moving of the workflow code back and forth from memory and the database. In other words, the workflow is dehydrated when moving from in memory to the database and then is subsequently re-hydrated when moved from the database back to in memory. During those trips, in order for a class to make the journey, it must implement the ISerializable interface. It turns out, this is really easy to do. Let’s take a look at the necessary components to make this happen. First, we need to implement the interface:

   1: using System;

   2: using System.Collections.Generic;

   3: using System.Linq;

   4: using System.Text;

   5: using System.Runtime.Serialization;

   6: using System.Runtime.Serialization.Formatters.Binary;

   7:  

   8: namespace wf_SubmitProposal

   9: {

  10:     [Serializable()]

  11:     public class ProposalData : ISerializable

Notice the attribute on the class [Serializable()].

By implementing the ISerializable interface, we inherit a GetObjectData method. In this method, we explicitly define the way the data is serialized for the class. This is easier than it might sound. In my example, I have a bunch of string and bool private member variables that capture the state of this object. Here is my GetObjectData method:

   1: #region ISerializable Members

   2:  

   3:        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)

   4:        {

   5:            info.AddValue("BranchHead", BranchHead);

   6:            info.AddValue("BranchHeadApproval", BranchHeadApproval);

   7:            info.AddValue("BranchHeadComments", BranchHeadComments);

   8:            info.AddValue("DivisionHead", DivisionHead);

   9:            info.AddValue("DivisionHeadApproval", DivisionApproval);

  10:            info.AddValue("DivisionHeadComments", DivisionComments);

  11:            info.AddValue("LMC", LineMgtCouncil);

  12:            info.AddValue("LMCApproval", LMCApproval);

  13:            info.AddValue("LMCComments", LMCComments);

  14:            info.AddValue("Author", Author);

  15:            info.AddValue("ProposalTitle", ProposalTitle);

  16:  

  17:        }

  18:  

  19:        #endregion

As you can see, we are simply creating essentially key/value pairs. The “key” is a string and the value is my property that exposes the private member variable. What is put in as a key is completely up to you. The importance of it is that you remember what it is on the deserialization method which we will show next.

So far, we have told the class how to take it’s state and serialize it. Now we need to know how to deserialize it. To accomplish this, we implement a constructor on the class that accepts the SerializationInfo and StreamingContext objects as parameters. In this constructor, we again use the key/value pairs to re-instantiate our private member variables, thus placing the object back to the state that it was in prior to serialization. How do we do that? Let’s take a look:

   1: public ProposalData(SerializationInfo info, StreamingContext ctxt)

   2:         {

   3:             mBranchHead = (string)info.GetValue("BranchHead", typeof(string));

   4:             mBHApproval = (bool)info.GetValue("BranchHeadApproval", typeof(bool));

   5:             mBHComments = (string)info.GetValue("BranchHeadComments", typeof(string));

   6:             mDivisionHead = (string)info.GetValue("DivisionHead", typeof(string));

   7:             mDivApproval = (bool)info.GetValue("DivisionHeadApproval", typeof(bool));

   8:             mDivComments = (string)info.GetValue("DivisionHeadComments", typeof(string));

   9:             mLineMgtCouncil = (string)info.GetValue("LMC", typeof(string));

  10:             mLMCApproval = (bool)info.GetValue("LMCApproval", typeof(bool));

  11:             mLMCComments = (string)info.GetValue("LMCComments", typeof(string));

  12:             mAuthor = (string)info.GetValue("Author", typeof(string));

  13:             mProposalTitle = (string)info.GetValue("ProposalTitle", typeof(string));

  14:         }

As you can see, I am setting my private member variable to the key/value pair that it represents. Be sure that you cast it to the appropriate type.

Once you implement the ISerializable interface, you can use classes inside your workflows all day long!  Open-mouthed smileOf course, there are tons of other reasons way you would need to implement ISerializable. SharePoint Workflows are just one example of the utility of this interface.

Good luck coding! Ninja

Advertisements

About lelandholmquest

After serving in the Navy as a Reactor Operator on fast attack submarines, I earned both a Bachelor's and Masters in Information Technology from American InterContinental University and am currently working on my doctorate. I have a beautiful wife and two of the sweetest daughters a man could ask for. And I work for the greatest company: Microsoft. At Microsoft I work on the knowledge management system for Microsoft Services: Campus on Office 365.
This entry was posted in C# Programming, SharePoint Coding, Workflows and tagged , . Bookmark the permalink.

One Response to Implementing ISerializable to facilitate workflow re-hydration

  1. Pingback: Implementing ISerializable to facilitate workflow re-hydration « madhavan

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s