Feeds:
Posts
Comments

Archive for November, 2010

When you rehost Workflow Foundation designer, sometimes it’s necessary for you to know the “scoped” variables to allow the user to choose from a list, for instance.

In order to make it you must navigate the Model tree from a given Activity (for instance the Activity bound to your Activity designer) using an helper method like this:

 

    ''' <summary>
    ''' Returns all the variables that the given scope could see... near->far ordering.
    ''' </summary>
    ''' <param name="Activity"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GetScopedVariables(
                    ByVal Activity As ModelItem,
                    ByVal TypeFilter As System.Type) As List(Of ModelItem)

        Dim vars As New List(Of ModelItem)

        Do While Not Activity Is Nothing

            If GetType(Activity).IsAssignableFrom(Activity.ItemType) Then
                ' we found an activity now inspect the properties to find the "variables" collection
                ' note: this is only a suggested approach, but not the best/or standard one. 
                '       It means we are not able to get all teh variables that are created by other means.
                Dim propVariables As ModelProperty = Activity.Properties("Variables")

                If Not propVariables Is Nothing Then
                    ' now get all the variables into the variable collectio.
                    If TypeFilter Is Nothing Then
                        vars.AddRange(propVariables.Collection)
                    Else
                        ' take only the variables that respect the requested typefilter!
                        vars.AddRange(propVariables.Collection.Where(
                            Function(mi As ModelItem) As Boolean
                                Return TypeFilter.IsAssignableFrom(mi.ItemType.GetGenericArguments(0))
                            End Function))
                    End If
                End If
            End If

            ' get parent object....
            Activity = Activity.Parent
        Loop

        Return vars

    End Function

This method provides also type filtering, meaning that you get all scoped variables compatible with a given input type.

Hope this helps someone trying to do the same.

Advertisements

Read Full Post »

The new WF4 version is going to include a lot of enhancements both on the designer side workflow services definition versioning dynamic update…

Let me enumerate a few:

  • C# expressions
  • Errors when connectors not applied.
  • Annotations
  • Auto-connect (drag&Drop)
  • State Machine
  • Multi-assign
  • SQL/State machine activities previously on Codeplex are not include
  • Http Activities (POST/GET/…)
  • Dynamic Update (definition version recognition and update map)
  • Other stuff…

Great job guys!

Read Full Post »

Here at PAT we are developing, among many other things Occhiolino, a new BPM solution that initially will work for our applications, but targeted to be adapted to others by standard means (SOAP) as well as through custom connectors.

We built is using the new Workflow Foundation 4.0 shipped along with the .NET Framework 4.0.

We rehosted both the designer and the workflow runtime.

Designer

On the designer side, we customized the way the property editor behaves on the rehosted environment.

In fact, for a Business Analyst is not easy to write flows using the out-of-the-box behavior. If you need better design time support “for free” (aka Intellisense) you should have the Visual Studio IDE.

We are going to implement our Intellisense support, but this sounds not enough.

image

On the left-down-side we provided a property editor, that allows for each Expression Editor provide a context-specific expression. This is very powerful yet simple to use.

Well, we basically provide many property-specific features there:

  • List of compatible scoped variables and arguments
  • List of possible “expression templates” (where implemented by the provider).

The coolest thing is the this last one… “expression templates”. This is useful when you need to choose from predefined values, –or- when you need to choose from pre-defined expression types.

For instance, let’s take a quick example. Let’s say you have an activity “Change Ticket Status”. This Activity obviously have the property where to store the “Target Status”, right? Now, … in order to take advantage of arguments, we should have an expression editor there. But what IF the Business Analyst (BA) already knows its status and just like to write a constant value there? The BA needs to know the status code… and write it there.

We did better. We provided a “designer feature” that allows our property editor to gather a list of expression templates from the “Ticket Status Property”.

We can also provide a variable-creation logic, which is more simple. By pressing Create New Variable button you come to a “new variable” form where you define the name and choose a compatible type (in this case the type does not have other compatible types so the list is locked):

image

The UI here is MUCH more simpler to use that the out-of-the-box one. Because we add also human-readable description for the types (provided by some designer attributes we apply to types), and filtering on both description and type name.

Workflow Execution Monitor

From the designer console, you can see the workflow queue updated in real time:

image

We also provided a debugger feature that allows the user to display from the designer, the status and the trace of all the execution along with parameters.

image

This was done adding a TrackingPartecipant that stores the history on our own table, that, in turn, is displayed on this page.

Server

We host all our services on our own WCF services. We have one administration service that allows the designer to perform all the “designer/administration” stuff.

We also provide a “Client” service that allows external applications to connect to the “Events” where our Workflow Definitions are attached.

We track versions of the same definition – in order to maintain compatibility with workflows already started – and also we provide Persistence support to all our workflows.

Human Interaction

We provided a metadata-driven set of clients that allows the user to provide data to flows at any stage required by the Business Analyst:

image

All this stuff is interfaced externally to the End-users through:

  • A “traylet” Windows-application
  • A multibrowser lightweight web application where the end-user could provide answer and make the flow continue with the results.

image

We are going to provide in the future, “Human Interaction Clients” for other platforms, such as WP7, IPhone, Android.

I’ll provide further details on the persistence and provider-independence of this solution in a next post!

Keep tuned!

Read Full Post »

For anyone that likes to solve this issue, please look at this post explaining the way to solve it:

Resuming of workflows from InstanceStore in Workflow 4.0

For anyone hosting workflows on a own process (like I am doing – for example on a Windows Service) you should create your own Thread and at given intervals perform the check like this:

I wish to thank Stuart Langley from MS for this useful tip!

   1:   void ResumePendingFlows()
   2:      {
   3:        MInstanceStore store = new MyInstanceStore(); 
   4:        InstanceHandle handle = store.CreateInstanceHandle(null); 
   5:        InstanceOwner owner = store.Execute(handle, new CreateWorkflowOwnerCommand(), 
TimeSpan.MaxValue).InstanceOwner; 
   6:        store.DefaultInstanceOwner = owner; 
   7:        
   8:        bool hasRunnableWorkflows = false; 
   9:        
  10:        foreach (InstancePersistenceEvent currentEvent in store.WaitForEvents(handle, TimeSpan.Zero)) 
  11:        { 
  12:          if (currentEvent == HasRunnableWorkflowEvent.Value) 
  13:          { 
  14:            hasRunnableWorkflows = true; 
  15:            break; 
  16:          } 
  17:        } 
  18:        
  19:        if (hasRunnableWorkflows) 
  20:        { 
  21:          Console.WriteLine("Found runnable workflows");
  22:          WorkflowApplication app = new WorkflowApplication( .... ); 
  23:          app.InstanceStore = store; 
  24:          app.LoadRunnableInstance(); 
  25:          app.Run(); 
  26:        } 
  27:        else 
  28:        { 
  29:          Console.WriteLine("Did not find runnable workflows"); 
  30:        }
  31:      }
 
 
 

Read Full Post »

The Silverlight for Windows Phone Toolkit has been updated today with new cool components and features:

  • New Components
    • AutoCompleteBox
    • ListPicker
    • LongListSelector
    • Page Transitions
  • Existing Components
    • GestureService/GestureListener
    • ContextMenu
    • DatePicker
    • TimePicker
    • ToggleSwitch
    • WrapPanel

I am going to try them right now.

Read Full Post »