The introduction WF post has covered the basics. This is the first in a series of WF related posts, stay tuned!
Microsoft has included a state of the art designer with WF4 which means better rehosting capabilities. The designer’s main purpose is to provide a graphical representation of business processes. Rehosting the designer really means that it is easy to run it outside VS using our own applications.
WF4 ships with many activities and Visual Studio 2010 includes a template for creating activities. The two most common activities used for root control flow are Sequence and Flowchart. While any Activity can be executed as a workflow, these two provide the most common design patterns for business logic. Below is an example of a sequential workflow designed to process an order.

However the above workflow uses native WF activities. In a XAF domain we have business objects and we need to query/modify them and let XAF shape our application accordingly. For this purpose a set of XAF specific activities have been implemented. The next image is from the XAF WF designer toolbox.

NoPersistScope
The main purpose of this activity is to serve as a container that prevents workflow persistence. There are two cases when a workflow can be saved and unloaded. These are when the workflow server stops or is long running. In such cases the WF engine serializes the workflows in a database freeing up valuable memory. Furthermore when we think about NoPersistScope inside the XAF context, we realize that it helps to avoid session mixing or object state changing problems.
The following image shows all this in action.
Problems can occur if there is a Delay activity inside While as the workflow will unload after the delay interval has reached. However when the While is inside a NoPersistScope this problem is avoided. The result is that the object’s state will not change and the condition will remain valid. Moreover when workflow execution reaches the Delay activity it begins to persist the workflow instance. It will also try to serialize among other variables including those containing persistent objects and a serialization error will occur. Therefore all persistent object variables should be declared within NoPersistScope to avoid serialization errors.
ObjectSpaceTransactionScope
This is another container and shares characteristics with NoPersistScope since it is derived from it. As the name implies this activity has the knowledge needed to construct an IObjectSpace. The complexity of the name comes first from IObjectSpace and also from the transaction process of the activity (it does not unload).
When working with persistent objects, the recommended approach is short transactions. For example, reading data from a database, checking something, modifying, creating, deleting, committing changes and completing transactions. It is better to avoid use long running work flows when inside XPO transactions. Instead we can combine multiple ObjectSpaceTransactionScope activities in a long running workflow.
There are several ways to specify a ConnectionString for an ObjectSpaceTransactionScope:
-
Via its ConnectionString Property,
-
Via a special extension in WorkflowServiceHost,
-
Via an app.config entry,
Our WorkflowServer class adopts the second approach by default. Upon startup IObjectSpaceProvider is passed to its constructor and is embedded as an extension for each WorkflowServiceHost object. Of course alternatives exist, we can directly access the app.config from WF designer, by simply typing ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString for example.
IObjectSpace Activities
Activities such as CommitChanges, RollBack, DeleteObject, GetObjectByKey, FindObjectByCriteria, GetObjectsByCriteria, CreateObject, GetObjectKey delegate to IObjectSpace original methods.
TransactionalGetObjectSpace
There are IObjectSpace methods that are not wrapped into an activity, but could be useful in a workflow. In such cases we need to use the TransactionalGetObjectSpace activity. Firstly we declare an IObjectSpace variable and then use this to extract it from the parent TransactionalObjectSpaceScope. After that we drop the Assign activity or InvokeMethod activity and call any method of the IObjectSpace.
CreateObjectSpace
The primary scenario for the CreateObjectSpace activity is to manage the need for two or more ObjectSpace objects. To work with these objects we must place them inside a NoPersistScope activity. Usually, it is unnecessary to use the CreateObjectSpace activity except when we cannot implement our task with the help of the ObjectSpaceTransactionScope activity. As with NoPersistScope this is a low level activity.
The ObjectSpaceTransactionScope activity works in the following way. The CreateObjectSpace activity is automatically scheduled as the first activity. The created IObjectSpace object is then placed into the Context as a named item so all the child activities have access to it.
In the next post we will explore with XAF CRUD activities.
We would appreciate your feedback on this post. Has it been useful to you? Feel free to contact us with any further questions.
Free DevExpress Products – Get Your Copy Today
The following free DevExpress product offers remain available. Should you have any questions about the free offers below, please submit a ticket via the
DevExpress Support Center at your convenience. We’ll be happy to follow-up.