(or Designing Your Workflow Activity Class Hierarchy)
One of the questions that we've had to consider when designing our Workflow Activity Class Hierarchy is whether it is valuable to have our own Activity base class (derived from Activity and inherited by all of our activity classes).
Our answer was "Yes". We decided that there were several good reasons to create our own Activity base class. Here are the reasons and some explanation.
- Implement the Asynchronous Activity pattern for all our activities - I described this pattern and the reasons that you want to do this in a previous post. Basically, the idea is that we want all our activities to do their work on a background thread so that they are cancelable.
- Shared properties - there were a few properties that we felt like we wanted on all our activities. I won't get into the specifics of them, but this is a reason to create any base class.
- Common tracking and logging - we wrote a little bit of code associated with Activity tracking and logging information about the workflow. We wanted to be consistent in the way that we logged about activities starting and stopping, so we put this code into the base class. We even have some generic code that logs all the Properties for our activities using the property collection that is inherited from the actual Activity class.
Our base activity class gives us all this but here's the rub...
There are actually two Workflow Activity base classes. If you want to create a Composite activity (one that contains other activities), you have to derive that class from CompositeActivity instead of Activity. This is extremely unfortunate for us, because there were several activities that we wanted to create that were composite activities. But this means that they couldn't derive from our other base class. So, we had to re-implement some of the base classes functionality in our Composite activity class. This is why when I am designing a tree structure, I try not to make a separate base class for the tree nodes and the leaf nodes. Because, it screws up inheritance, polymorphism and a few other fancy OO words I can't recall.
Keep this gotcha in mind when you start planning your Activity class hierarchy!