Patrick:Hi,
In there the recommended way for long running workflows is to serialize the business objects needed for the activities with the workflow and then let WWF instantiate the objects again when the workflow continues.
You really think it reads like I recommend that?
The entire section titled "Business Objects as Workflow or Activity State" should scare the crap out of most people who'd consider doing such a thing. I was merely pointing out that it is possible to do, but only if you are willing to do all the work it took me two pages just to summarize (much less cover in detail)!
Perhaps I should have been more explicit with something like:
If you just read the past two pages and still think any sane person would choose to do this, please reconsider, because a sane person would not do this!
I thought that was reasonably clear, but apparently not. Sorry about that. Hopefully it is more clear now :)
RockfordLhotka:You really think it reads like I recommend that?
.... you talk about the difficulties with versioning the business object and then end with:RockfordLhotka:
It is important to realize that any dependency property values are serialized and persisted (typically in a database) if the workflow is unloaded before it completes. This means that the Project object instance exposed by these Project properties may be serialized!
That’s OK, because all CSLA .NET style business objects must be Serializable, and so the serialization will work fine. The fields in your object, and any child objects, will be serialized into a byte stream, which is then stored as part of the workflow’s state.
When the workflow is later loaded back into memory, its state is deserialized. Your business object is part of this state, so it is deserialized as well. This deserialization occurs before the workflow resumes running
RockfordLhotka:These techniques allow you to construct your business objects in a way that is safe for versioning, even if the business object is serialized and deserialized as part of a workflow’s state.
Well, there’s a difference between “ok idea”
and “recommend”.
It IS an ok idea. People do this (with or without CSLA). I’ve
seen it done numerous times, and it can work fine if you know what you are
doing and are willing to think through all the consequences.
I thought it was important to make people aware that it can be
done, and how to do it.
My intent was to be neutral on whether it should be done.
I’m not a WF expert. There are probably only a score of WF
experts in the world right now – it is too new, and not widely adopted
yet. I didn’t feel I could recommend for or against the idea, just throw
the possibilities out there so people can make their own choices.
Besides, as a version 1.0 technology, we won’t know what
really good practices are for 2 more versions. Nothing gets real stable or well
understood until version 3 :)
Rocky
Patrick:What I feel is missing is a sample of how to allow the workflow to set all associated business objects to null before suspending and then to reinstantiate them again on initialization.
This could maybe be done by implementing an interface on the workflow the WorkflowManager could automatically call, there might be events as part of WWF etc.
Patrick:What I feel is missing is a sample of how to allow the workflow to set all associated business objects to null before suspending and then to reinstantiate them again on initialization.
This could maybe be done by implementing an interface on the workflow the WorkflowManager could automatically call, there might be events as part of WWF etc.
Once there is a sample it becomes clearer that this is a "best practice" :).
I doubt that's the right approach. I suspect the right approach is to never expose a business object as a dependency property of an activity in the first place.
Activities must be independent black boxes. Atomic units of operation. You can't just run through all activities and blank their dependency properties before suspending the workflow - that flies in the face of the whole idea of workflow.
Personally, if I am going to be suspending a workflow, I just won't create dependency properties (or instance fields) that expose business objects, thus avoiding the whole issue. It is harder to build the workflow, because it forces a more "pure" mindset (message-passing between activities), but you dodge the whole serialization/versioning thing.
RockfordLhotka:Personally, if I am going to be suspending a workflow, I just won't create dependency properties (or instance fields) that expose business objects, thus avoiding the whole issue. It is harder to build the workflow, because it forces a more "pure" mindset (message-passing between activities), but you dodge the whole serialization/versioning thing.
Ultimately the issue comes down to this: serialization is not for persistence. Microsoft is quite clear on this point - and yet they unfortunately chose to use serialization to persist workflows (shows that the left hand doesn't always know what the right hand is doing).
Serialization should be used for transient data only, never persistent data. The BinaryFormatter has grown over the years such that it is capable of versioning reasonably well for limited changes to the shape of an object graph. But if a workflow is suspended for a long time, the changes you make to your object graph shapes may not be limited...
So I'd suggest that, for long-running/suspended workflows, you almost need to view all dependency properties and instance fields in activities like service contracts. Pretty limiting, and hopefully something that will have a better answer as WF matures over time.
Copyright (c) Marimer LLC