I've just uploaded a set of sample Windows Workflow Foundation activities for Microsoft Message Queue in the Winterdom.Workflow.Activities.Msmq assembly.


The MsmqSendActivity allows you to send a .NET object as an MSMQ message by just binding the activity to one of your workflow's properties and selecting the appropriate formatter (XmlMessageFormatter or BinaryFormatter). If the queue is transactional, you can put the activity inside a TransactionalScope activity.



The MsmqReceiveActivity allows you to receive an MSMQ message into a typed .NET object; the activity will do the deserialization based on the selected formatter. The activity can also be used inside an EventDrivenActivity so you can use it inside a Listen shape or in a StateMachine workflow to trigger state changes.


The samples include the following features:



  • Bindable properties, through both direct and attached dependency properties.
  • Design-Time support: each activity has a customized appearance. The MsmqReceiveActivity also shows the use of a custom activity designer to synthetize a property at design-time that supports binding.
  • Validation support: Both activities contain sample validators to ensure the required properties are configured correctly.

Here's a sample of how they could be used in XOML:

<SequentialWorkflowActivity

      x:Class="TestApp.SampleWorkflow2"

      x:Name="SampleWorkflow2"

      xmlns:ns0="clr-namespace:Winterdom.Workflow.Activities.Msmq;Assembly=Winterdom.Workflow.Activities.Msmq, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"

      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow">

    <TransactionScopeActivity x:Name="SendScope">

        <TransactionScopeActivity.TransactionOptions>

            <WorkflowTransactionOptions TimeoutDuration="00:00:30"

            IsolationLevel="Serializable" />

        .TransactionOptions>

        <ns0:MsmqSendActivity

            x:Name="SendMessage"

            Queue="{ActivityBind SampleWorkflow2,Path=QUEUE}"

            Label="{ActivityBind SampleWorkflow2,Path=_labelToSend}"

            IsTransactionalQueue="True">

            <ns0:MsmqSendActivity.MessageToSend>

                <ActivityBind Name="SampleWorkflow2" Path="_customerToSend" />

            ns0:MsmqSendActivity.MessageToSend>

        ns0:MsmqSendActivity>

    

    <ns0:MsmqReceiveActivity

         x:Name="ReceiveMessage"

         Queue="{ActivityBind SampleWorkflow2,Path=QUEUE}"

         ns0:MsmqReceiveActivity.Label="{ActivityBind SampleWorkflow2,Path=_labelReceived}"

         MessageType="{x:Type TestApp.Customer}"

         Label="{x:Null}">

        <ns0:MsmqReceiveActivity.MessageReceived>

            <ActivityBind Name="SampleWorkflow2" Path="_customerReceived" />

        ns0:MsmqReceiveActivity.MessageReceived>

    ns0:MsmqReceiveActivity>



If you plan to use the MsmqReceiveActivity, you'll need to configure the MsmqListenerService service into the WorkflowRuntime, like this:

WorkflowRuntime workflowRuntime = new WorkflowRuntime("ConsoleApplication");

workflowRuntime.AddService(new MsmqListenerService());

Update: The sample activities can be downloaded from here.


I hope to improve them and add new functionality (if I can) to them, so if you have any comments/bugs/features, do let me know! One feature I would definitely like to implement is correlation support, but as of now I'm not entirely sure what the best approach for that might be.



Tomas Restrepo

Software developer located in Colombia.