<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">The Problem Solver</title><subtitle type="html">Tell me and I will forget&lt;br /&gt;
Show me and I will remember&lt;br /&gt;
Involve me and I will understand&lt;br /&gt;
- Confucius -</subtitle><id>http://msmvps.com/blogs/theproblemsolver/atom.aspx</id><link rel="alternate" type="text/html" href="http://msmvps.com/blogs/theproblemsolver/default.aspx" /><link rel="self" type="application/atom+xml" href="http://msmvps.com/blogs/theproblemsolver/atom.aspx" /><generator uri="http://communityserver.org" version="4.0.30619.63">Community Server</generator><updated>2008-07-28T21:48:36Z</updated><entry><title>Versioning long running workflows part 4</title><link rel="alternate" type="text/html" href="/blogs/theproblemsolver/archive/2008/09/22/versioning-long-running-workflows-part-4.aspx" /><id>/blogs/theproblemsolver/archive/2008/09/22/versioning-long-running-workflows-part-4.aspx</id><published>2008-09-22T12:23:06Z</published><updated>2008-09-22T12:23:06Z</updated><content type="html">&lt;a href="http://msmvps.com/blogs/theproblemsolver/archive/2008/09/10/versioning-long-running-workfows.aspx"&gt;Part 1&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/theproblemsolver/archive/2008/09/11/versioning-long-running-workflows-part-2.aspx"&gt;Part 2&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/theproblemsolver/archive/2008/09/16/versioning-long-running-workfows-part-3.aspx"&gt;Part 3&lt;br /&gt;Part 4&lt;/a&gt;  &lt;p&gt;In the previous blog posts we made sure we could have multiple versions of the same workflow running side by side. This ability is one of the more powerful concepts of WF and a real must have for long running business applications. &lt;/p&gt; &lt;h2&gt;A quick recap. &lt;/h2&gt; &lt;p&gt;Always version your assemblies by giving them a strong name. Make sure the runtime can find each version of the assembly by pointing the CLR to the right version using the configuration\runtimeassemblyBinding\dependentAssembly\assemblyIdentity\codeBase in your App.Config (or Web.Config in the case of a web application). And make sure you use all types and interfaces from the same version as the workflow or, somewhat easier, stick to using basic CLR types when sending messages.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;Great, but what about fixing bugs?&lt;/h2&gt; &lt;p&gt;All the versioning is very nice but the simple fact is that sooner or later you are going to find a bug in your code and need to fix a specific assembly. In that case it would not be very nice if the workflow would keep on running with the buggy code. No in that case you would very much like to be able to dehydrate the worfklows and have them use the patched version of the assembly instead of the original one.&lt;/p&gt; &lt;p&gt;Fortunately this is easy to do, and again due to the standard binary serialization format Windows Workflow Foundation uses, completely standard .NET.&lt;/p&gt; &lt;p&gt;Again the trick is versioning the assembly and using the App.Config to redirect the runtime to the correct version. So just as I demonstrated in the previous posts I need to strongly sign the assembly. Next when we want to fix a bug in the assembly we need to update the version number and redirect the CLR to the new version. The last part is done using the following config file:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color:#a31515;"&gt;xml &lt;/span&gt;&lt;span style="color:red;"&gt;version&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;1.0&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;encoding&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;utf-8&lt;/span&gt;&amp;quot; &lt;span style="color:blue;"&gt;?&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;configuration&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;runtime&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;assemblyBinding &lt;/span&gt;&lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;urn:schemas-microsoft-com:asm.v1&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;dependentAssembly&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;assemblyIdentity &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;WorkflowLibrary1&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;publicKeyToken&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;8afb6d596a769080&lt;/span&gt;&amp;quot; &lt;span style="color:blue;"&gt;/&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bindingRedirect &lt;/span&gt;&lt;span style="color:red;"&gt;oldVersion&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;1.0.0.0&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;newVersion&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;1.0.1.0&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;
      &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;dependentAssembly&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;assemblyBinding&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;runtime&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;configuration&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;To demonstrate the effect the workflow below is started with a parameter that indicates the assembly version it was when started and prints this, long with the current assembly version, on the screen. as you can see the first workflow was started with version 1.0.0.0 but the assembly actually executing is updated to 1.0.1.0. In contrast the second workflow was created using the assembly 1.0.1.0.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkflowspart4_5F00_C5B1/image_5F00_2.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="218" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkflowspart4_5F00_C5B1/image_5F00_thumb.png" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h2&gt;So why bother to update the version number in the first place?&lt;/h2&gt;
&lt;p&gt;After all you could just leave the version number as is and replace the assembly. The main disadvantage is that it makes it harder to see which version was executing when a new bug report comes in. Was this the patched assembly and is the bug still there under specific circumstances? On other words: was the bug fix buggy&lt;img src="http://msmvps.com/emoticons/emotion-6.gif" alt="Sad" /&gt;. Or is the system still using the original assembly, and was the update not done correctly? Best just to avoid these kind of problems and make sure you can see which version either by looking at the assembly file properties or by having an error handler print all loaded assemblies, including version number.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.theproblemsolver.nl/"&gt;www.TheProblemSolver.nl &lt;/a&gt;&lt;br /&gt;&lt;a href="http://wiki.windowsworkflowfoundation.eu/"&gt;Wiki.WindowsWorkflowFoundation.eu&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1648514" width="1" height="1"&gt;</content><author><name>Maurice</name><uri>http://msmvps.com/members/Maurice/default.aspx</uri></author><category term=".NET" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/.NET/default.aspx" /><category term="NetFx3" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/NetFx3/default.aspx" /><category term="Workflow" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/Workflow/default.aspx" /><category term="VB" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/VB/default.aspx" /><category term="DevCenter" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/DevCenter/default.aspx" /></entry><entry><title>Versioning long running workfows part 3</title><link rel="alternate" type="text/html" href="/blogs/theproblemsolver/archive/2008/09/16/versioning-long-running-workfows-part-3.aspx" /><id>/blogs/theproblemsolver/archive/2008/09/16/versioning-long-running-workfows-part-3.aspx</id><published>2008-09-16T14:29:07Z</published><updated>2008-09-16T14:29:07Z</updated><content type="html">&lt;a href="http://msmvps.com/blogs/theproblemsolver/archive/2008/09/10/versioning-long-running-workfows.aspx"&gt;Part 1&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/theproblemsolver/archive/2008/09/11/versioning-long-running-workflows-part-2.aspx"&gt;Part 2&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/theproblemsolver/archive/2008/09/16/versioning-long-running-workfows-part-3.aspx"&gt;Part 3&lt;br /&gt;Part 4&lt;/a&gt;  &lt;p&gt;In the first article of this series I demonstrated how to get multiple versions of a workflow running side by side in the same&amp;nbsp; workflow runtime. The most important thing was that you need to keep every version of the assembly around and use the assemblyBinding element in the app.config to let the runtime know where each version was on disk. Once done life was good &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;&lt;/p&gt; &lt;p&gt;In the second part I demonstrated how a HandleExternalEventActivity was version dependent and you needed to use the version specific service to send a message to the workflow. It worked but the as the code was not exactly pretty life was just ok &lt;img src="http://msmvps.com/emoticons/emotion-6.gif" alt="Sad" /&gt;.&lt;/p&gt; &lt;h2&gt;What is wrong with the HandleExternalEventActivity?&lt;/h2&gt; &lt;p&gt;Well there is nothing really wrong with the HandleExternalEventActivity but it is a very thin layer over the actual workflow structures it tries to hide. And these structures are the workflow queuing mechanism! Internally everything is turned into a message and send through a queue. So if this is only a thin abstraction layer why not use the original API in the first place. &lt;/p&gt; &lt;p&gt;&lt;strong&gt;That is exactly what I advise, leave the external data exchange mechanism for what it is and just create a custom workflow activity.&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;What does it take to implement the same behavior using a custom activity? Not a whole lot actually so lets take a look.&lt;/p&gt; &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfowspart3_5F00_D81B/image_5F00_2.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="484" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfowspart3_5F00_D81B/image_5F00_thumb.png" width="503" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Above is the new workflow with the custom activity.&lt;/p&gt; &lt;p&gt;Because the custom activity is used as the first child in one of the branches of a ListenActivity it must implement the IEventActivity interface and we must override the Execute method to do something once a message is found in the queue. &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;using &lt;/span&gt;System;
&lt;span style="color:blue;"&gt;using &lt;/span&gt;System.Workflow.Activities;
&lt;span style="color:blue;"&gt;using &lt;/span&gt;System.Workflow.ComponentModel;
&lt;span style="color:blue;"&gt;using &lt;/span&gt;System.Workflow.Runtime;

&lt;span style="color:blue;"&gt;namespace &lt;/span&gt;WorkflowLibrary1
{
    &lt;span style="color:blue;"&gt;public partial class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;MyActivity &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;Activity&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;IEventActivity
    &lt;/span&gt;{
        &lt;span style="color:blue;"&gt;public static string &lt;/span&gt;TheQueueName = &lt;span style="color:#a31515;"&gt;&amp;quot;MyActivityQueueName&amp;quot;&lt;/span&gt;;

        &lt;span style="color:blue;"&gt;protected override &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ActivityExecutionStatus &lt;/span&gt;Execute(
            &lt;span style="color:#2b91af;"&gt;ActivityExecutionContext &lt;/span&gt;executionContext)
        {
            &lt;span style="color:#2b91af;"&gt;WorkflowQueuingService &lt;/span&gt;wqs = executionContext.GetService&amp;lt;&lt;span style="color:#2b91af;"&gt;WorkflowQueuingService&lt;/span&gt;&amp;gt;();
            &lt;span style="color:#2b91af;"&gt;WorkflowQueue &lt;/span&gt;queue = wqs.GetWorkflowQueue(QueueName);
            &lt;span style="color:blue;"&gt;object &lt;/span&gt;data = queue.Dequeue();
            &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Received {0} in {1}&amp;quot;&lt;/span&gt;, data, GetType().Assembly.FullName);
            &lt;span style="color:blue;"&gt;return base&lt;/span&gt;.Execute(executionContext);
        }

        &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IComparable &lt;/span&gt;QueueName
        {
            &lt;span style="color:blue;"&gt;get &lt;/span&gt;{ &lt;span style="color:blue;"&gt;return &lt;/span&gt;TheQueueName; }
        }

        &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Subscribe(
            &lt;span style="color:#2b91af;"&gt;ActivityExecutionContext &lt;/span&gt;parentContext, 
            &lt;span style="color:#2b91af;"&gt;IActivityEventListener&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;QueueEventArgs&lt;/span&gt;&amp;gt; parentEventHandler)
        {
            &lt;span style="color:#2b91af;"&gt;WorkflowQueuingService &lt;/span&gt;wqs = parentContext.GetService&amp;lt;&lt;span style="color:#2b91af;"&gt;WorkflowQueuingService&lt;/span&gt;&amp;gt;();
            &lt;span style="color:#2b91af;"&gt;WorkflowQueue &lt;/span&gt;queue = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;
            &lt;span style="color:blue;"&gt;if &lt;/span&gt;(wqs.Exists(TheQueueName))
                queue = wqs.GetWorkflowQueue(TheQueueName);
            &lt;span style="color:blue;"&gt;else
                &lt;/span&gt;queue = wqs.CreateWorkflowQueue(QueueName, &lt;span style="color:blue;"&gt;true&lt;/span&gt;);
            queue.RegisterForQueueItemAvailable(parentEventHandler);
        }

        &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Unsubscribe(
            &lt;span style="color:#2b91af;"&gt;ActivityExecutionContext &lt;/span&gt;parentContext, 
            &lt;span style="color:#2b91af;"&gt;IActivityEventListener&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;QueueEventArgs&lt;/span&gt;&amp;gt; parentEventHandler)
        {
            &lt;span style="color:#2b91af;"&gt;WorkflowQueuingService &lt;/span&gt;wqs = parentContext.GetService&amp;lt;&lt;span style="color:#2b91af;"&gt;WorkflowQueuingService&lt;/span&gt;&amp;gt;();
            &lt;span style="color:#2b91af;"&gt;WorkflowQueue &lt;/span&gt;queue = wqs.GetWorkflowQueue(TheQueueName);
            queue.UnregisterForQueueItemAvailable(parentEventHandler);
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I am not going to explain the details except that the message is read in the Execute and is printed as is along with the assembly version. And guess what, If I create multiple versions of the workflow and run them side by side life is good &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfowspart3_5F00_D81B/image_5F00_4.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="321" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfowspart3_5F00_D81B/image_5F00_thumb_5F00_1.png" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Sending the data was easy too with only the following code:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;static void &lt;/span&gt;SendEvent1(&lt;span style="color:#2b91af;"&gt;WorkflowRuntime &lt;/span&gt;workflowRuntime, &lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;instanceId)
{
    &lt;span style="color:#2b91af;"&gt;WorkflowInstance &lt;/span&gt;instance = workflowRuntime.GetWorkflow(instanceId);
    instance.EnqueueItem(&lt;span style="color:#2b91af;"&gt;MyActivity&lt;/span&gt;.TheQueueName, 1, &lt;span style="color:blue;"&gt;null&lt;/span&gt;, &lt;span style="color:blue;"&gt;null&lt;/span&gt;);
}
&lt;/pre&gt;
&lt;p&gt;However the data send in this simple example is only an integer. Lets see what happens when we use a custom object instead of the single integer.&lt;/p&gt;
&lt;h2&gt;The case of the custom message type&lt;/h2&gt;
&lt;p&gt;In the previous example everything worked just fine because we only send in a real simple data type, an integer. However when we switch to a custom type things are less perfect &lt;img src="http://msmvps.com/emoticons/emotion-6.gif" alt="Sad" /&gt;.&lt;/p&gt;
&lt;p&gt;For this example I am using the following data type:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;namespace &lt;/span&gt;WorkflowLibrary1
{
    &lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;MyData
    &lt;/span&gt;{
        &lt;span style="color:blue;"&gt;public &lt;/span&gt;MyData(&lt;span style="color:blue;"&gt;int &lt;/span&gt;data)
        {
            TheData = data;
        }

        &lt;span style="color:blue;"&gt;public int &lt;/span&gt;TheData { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

        &lt;span style="color:blue;"&gt;public override string &lt;/span&gt;ToString()
        {
            &lt;span style="color:blue;"&gt;return string&lt;/span&gt;.Format(&lt;span style="color:#a31515;"&gt;&amp;quot;Data = {0}&amp;quot;&lt;/span&gt;, TheData);
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Still real simple but non the less a custom type we can version along with the workflow and its activities. The code to send the message becomes as follows:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;static void &lt;/span&gt;SendEvent1(&lt;span style="color:#2b91af;"&gt;WorkflowRuntime &lt;/span&gt;workflowRuntime, &lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;instanceId)
{
    &lt;span style="color:#2b91af;"&gt;WorkflowInstance &lt;/span&gt;instance = workflowRuntime.GetWorkflow(instanceId);
    &lt;span style="color:#2b91af;"&gt;MyData &lt;/span&gt;data = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;MyData&lt;/span&gt;(1);
    instance.EnqueueItem(&lt;span style="color:#2b91af;"&gt;MyActivity&lt;/span&gt;.TheQueueName, data, &lt;span style="color:blue;"&gt;null&lt;/span&gt;, &lt;span style="color:blue;"&gt;null&lt;/span&gt;);
}
&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Again not a spectacular change as we only substitute the integer for an object of type MyData. The activity execute changes to the following:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;protected override &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ActivityExecutionStatus &lt;/span&gt;Execute(
    &lt;span style="color:#2b91af;"&gt;ActivityExecutionContext &lt;/span&gt;executionContext)
{
    &lt;span style="color:#2b91af;"&gt;WorkflowQueuingService &lt;/span&gt;wqs = executionContext.GetService&amp;lt;&lt;span style="color:#2b91af;"&gt;WorkflowQueuingService&lt;/span&gt;&amp;gt;();
    &lt;span style="color:#2b91af;"&gt;WorkflowQueue &lt;/span&gt;queue = wqs.GetWorkflowQueue(QueueName);
    &lt;span style="color:#2b91af;"&gt;MyData &lt;/span&gt;data = (&lt;span style="color:#2b91af;"&gt;MyData&lt;/span&gt;)queue.Dequeue();
    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Received {0} in {1}&amp;quot;&lt;/span&gt;, data, GetType().Assembly.FullName);
    &lt;span style="color:blue;"&gt;return base&lt;/span&gt;.Execute(executionContext);
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Again no big change, all we are doing is casting the data from the queue to be of type MyData. When we run this with a workflow started using the latest version everything is just fine but when I send a message to a workflow version 1.0.0.0 we receive the following InvalidCastException message:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Unable to cast object of type &amp;#39;WorkflowLibrary1.MyData&amp;#39; to type &amp;#39;WorkflowLibrary1.MyData&amp;#39;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfowspart3_5F00_D81B/image_5F00_8.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="283" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfowspart3_5F00_D81B/image_5F00_thumb_5F00_3.png" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;That message seems kind of weird as it is claiming that we cannot cast MyData to MyData!. Weird as this may seem it is completely true!&lt;/p&gt;
&lt;p&gt;The problem, and things would have been clearer of the message include this information is that we cannot cast between two different versions of the same type as they are really different types.&lt;/p&gt;
&lt;h2&gt;The solution&lt;/h2&gt;
&lt;p&gt;Just like the previous time the solution is to create an object of the same type as was used in the custom workflow activity. The concept is pretty much the same as last time with the ExternalDataExchangeService and requires a bit of reflection.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;static void &lt;/span&gt;SendEvent2(&lt;span style="color:#2b91af;"&gt;WorkflowRuntime &lt;/span&gt;workflowRuntime, &lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;instanceId)
{
    &lt;span style="color:#2b91af;"&gt;WorkflowInstance &lt;/span&gt;instance = workflowRuntime.GetWorkflow(instanceId);
    &lt;span style="color:#2b91af;"&gt;Assembly &lt;/span&gt;assembly = instance.GetWorkflowDefinition().GetType().Assembly;
    &lt;span style="color:#2b91af;"&gt;Type &lt;/span&gt;type = assembly.GetType(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;MyData&lt;/span&gt;).FullName);
    &lt;span style="color:blue;"&gt;object &lt;/span&gt;data =&lt;span style="color:#2b91af;"&gt;Activator&lt;/span&gt;.CreateInstance(type, &lt;span style="color:blue;"&gt;new object&lt;/span&gt;[] {1});
    instance.EnqueueItem(&lt;span style="color:#2b91af;"&gt;MyActivity&lt;/span&gt;.TheQueueName, data, &lt;span style="color:blue;"&gt;null&lt;/span&gt;, &lt;span style="color:blue;"&gt;null&lt;/span&gt;);
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;using this code both the workflow and the runtime are perfectly happy. That said, personally I don&amp;#39;t really like having to resort to reflection every time &lt;img src="http://msmvps.com/emoticons/emotion-6.gif" alt="Sad" /&gt; 
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfowspart3_5F00_D81B/image_5F00_10.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="321" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfowspart3_5F00_D81B/image_5F00_thumb_5F00_4.png" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;So instead of using typed objects you might just want to resort to using basic framework objects which will remain the same version until a major .NET framework upgrade. One easy way to send data is just embed it in an XML document or, just as the workflow parameters, a Dictionary&amp;lt;string, object&amp;gt; and pass that along.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.theproblemsolver.nl/"&gt;www.TheProblemSolver.nl &lt;/a&gt;&lt;br /&gt;&lt;a href="http://wiki.windowsworkflowfoundation.eu/"&gt;Wiki.WindowsWorkflowFoundation.eu&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1647917" width="1" height="1"&gt;</content><author><name>Maurice</name><uri>http://msmvps.com/members/Maurice/default.aspx</uri></author><category term=".NET" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/.NET/default.aspx" /><category term="NetFx3" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/NetFx3/default.aspx" /><category term="Workflow" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/Workflow/default.aspx" /><category term="DevCenter" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/DevCenter/default.aspx" /></entry><entry><title>A bit more about using TransactionScopeActivity within a ReceiveActivity</title><link rel="alternate" type="text/html" href="/blogs/theproblemsolver/archive/2008/09/16/a-bit-more-about-using-transactionscopeactivity-within-a-receiveactivity.aspx" /><id>/blogs/theproblemsolver/archive/2008/09/16/a-bit-more-about-using-transactionscopeactivity-within-a-receiveactivity.aspx</id><published>2008-09-16T10:06:01Z</published><updated>2008-09-16T10:06:01Z</updated><content type="html">&lt;a href="http://msmvps.com/blogs/theproblemsolver/archive/2008/08/06/using-a-transactionscopeactivity-with-a-wcf-receiveactivity.aspx"&gt;Part 1&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/theproblemsolver/archive/2008/08/08/more-on-using-a-transactionscopeactivity-within-a-receiveactivity.aspx"&gt;part 2&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/theproblemsolver/archive/2008/08/13/using-a-transactionscopeactivity-within-a-receiveactivity-in-a-state-machine-workflow.aspx"&gt;Part 3&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/theproblemsolver/archive/2008/09/16/a-bit-more-about-using-transactionscopeactivity-within-a-receiveactivity.aspx"&gt;Part 4&lt;/a&gt;  &lt;p&gt;You may recall my previous posts about using the TransactionScopeActivity within a ReceiveActivity and all the nasty issues we ran into. Just in case you want to read them again: &lt;a href="http://msmvps.com/blogs/theproblemsolver/archive/2008/08/06/using-a-transactionscopeactivity-with-a-wcf-receiveactivity.aspx"&gt;one&lt;/a&gt;, &lt;a href="http://msmvps.com/blogs/theproblemsolver/archive/2008/08/08/more-on-using-a-transactionscopeactivity-within-a-receiveactivity.aspx"&gt;two&lt;/a&gt; and &lt;a href="http://msmvps.com/blogs/theproblemsolver/archive/2008/08/13/using-a-transactionscopeactivity-within-a-receiveactivity-in-a-state-machine-workflow.aspx"&gt;three&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;As it turn out this is an intentionally not supported scenario at the moment. If we read the docs for the &lt;a href="http://msdn.microsoft.com/en-us/library/system.workflow.activities.receiveactivity.aspx"&gt;ReceiveActivity&lt;/a&gt; we can find the following note:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;To ensure that persistence performs properly and does not persist transient messages, make sure that child activities of the ReceiveActivity do not persist by themselves. This can occur if the child activities go idle when a persistence provider was created with UnloadOnIdle set to true, for instance.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The note uses the UnloadOnIdle as an example but the persistence part is just as much true for the &lt;a href="http://msdn.microsoft.com/en-us/library/system.workflow.componentmodel.transactionscopeactivity(VS.85).aspx"&gt;TransactionScopeActivity&lt;/a&gt; as this persists the state. Of course there is no similar warning in the TransactionScopeActivity docs &lt;img src="http://msmvps.com/emoticons/emotion-6.gif" alt="Sad" /&gt; and the activity validation fails to warn us either so there is definitely some room for improvement here.&lt;/p&gt; &lt;p&gt;But rumor has it that this improvement is coming &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt; The rumor says that not only will we be able use a TransactionScopeActivity inside of a ReceiveActivity but we can even go a step further in being able to flow a transaction from the client through the WCF request into the workflow and have the TransactionScopeActivity&amp;nbsp; participate in the same transaction. Nice but I guess we will have to wait for the PDC before we get all the details.&lt;/p&gt; &lt;p&gt;Enjoy!&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.theproblemsolver.nl/"&gt;www.TheProblemSolver.nl &lt;/a&gt;&lt;br /&gt;&lt;a href="http://wiki.windowsworkflowfoundation.eu/"&gt;Wiki.WindowsWorkflowFoundation.eu&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1647888" width="1" height="1"&gt;</content><author><name>Maurice</name><uri>http://msmvps.com/members/Maurice/default.aspx</uri></author><category term=".NET" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/.NET/default.aspx" /><category term="NetFx3" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/NetFx3/default.aspx" /><category term="Workflow" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/Workflow/default.aspx" /><category term="WCF" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/WCF/default.aspx" /><category term="VB" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/VB/default.aspx" /><category term="DevCenter" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/DevCenter/default.aspx" /></entry><entry><title>Versioning long running workflows part 2</title><link rel="alternate" type="text/html" href="/blogs/theproblemsolver/archive/2008/09/11/versioning-long-running-workflows-part-2.aspx" /><id>/blogs/theproblemsolver/archive/2008/09/11/versioning-long-running-workflows-part-2.aspx</id><published>2008-09-11T18:53:11Z</published><updated>2008-09-11T18:53:11Z</updated><content type="html">&lt;a href="http://msmvps.com/blogs/theproblemsolver/archive/2008/09/10/versioning-long-running-workfows.aspx"&gt;Part 1&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/theproblemsolver/archive/2008/09/11/versioning-long-running-workflows-part-2.aspx"&gt;Part 2&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/theproblemsolver/archive/2008/09/16/versioning-long-running-workfows-part-3.aspx"&gt;Part 3&lt;br /&gt;Part 4&lt;/a&gt;  &lt;p&gt;In my &lt;a href="http://msmvps.com/blogs/theproblemsolver/archive/2008/09/10/versioning-long-running-workfows.aspx"&gt;previous post&lt;/a&gt; I demonstrated how to keep multiple versions of an assembly around and how to use the assemblyBinding element in the app.config to let the runtime load multiple versions of a worklfow. In the end we had both workflows, the first in assembly 1.0.0.0 and the second in assembly 2.0.0.0, running and life seemed to be good &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;&lt;/p&gt; &lt;p&gt;So is there more to write on the subject? Yes unfortunately there are still some potential problems that need to be addressed &lt;img src="http://msmvps.com/emoticons/emotion-6.gif" alt="Sad" /&gt;.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;The pitfalls of External Data Exchange&lt;/h2&gt; &lt;p&gt;Lets take a look at what happens if we add a HandleExternalEventActivity to the mix. This HandleExternalEventActivity can be used to have a workflow react to input from an external data exchange service, sometimes called local communication.&lt;/p&gt; &lt;p&gt;Lets change the workflow to reflect the following:&lt;/p&gt; &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkflowspart2_5F00_DFB3/image_5F00_4.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="484" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkflowspart2_5F00_DFB3/image_5F00_thumb_5F00_1.png" width="500" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;In this workflow I am waiting for either a DelayActivity to fire or an event to be raised from an external service. Like before the activities are emended in a permanent loop so the workflow is never finished.&lt;/p&gt; &lt;p&gt;I have kept the external data exchange service real simple. The interface looks like this:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;using &lt;/span&gt;System;
&lt;span style="color:blue;"&gt;using &lt;/span&gt;System.Workflow.Activities;

&lt;span style="color:blue;"&gt;namespace &lt;/span&gt;WorkflowLibrary1
{
    [&lt;span style="color:#2b91af;"&gt;ExternalDataExchange&lt;/span&gt;]
    &lt;span style="color:blue;"&gt;public interface &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IMyService
    &lt;/span&gt;{
        &lt;span style="color:blue;"&gt;event &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;EventHandler&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;MyEventArgs&lt;/span&gt;&amp;gt; TheEvent;
    }
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;The implementation like this:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;using &lt;/span&gt;System;

&lt;span style="color:blue;"&gt;namespace &lt;/span&gt;WorkflowLibrary1
{
    &lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;MyService &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;IMyService
    &lt;/span&gt;{
        &lt;span style="color:blue;"&gt;public event &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;EventHandler&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;MyEventArgs&lt;/span&gt;&amp;gt; TheEvent;

        &lt;span style="color:blue;"&gt;public void &lt;/span&gt;OnTheEvent(&lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;instanceId)
        {
            &lt;span style="color:blue;"&gt;if &lt;/span&gt;(TheEvent != &lt;span style="color:blue;"&gt;null &lt;/span&gt;&amp;amp;&amp;amp; instanceId != &lt;span style="color:#2b91af;"&gt;Guid&lt;/span&gt;.Empty)
            {
                &lt;span style="color:#2b91af;"&gt;MyEventArgs &lt;/span&gt;args = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;MyEventArgs&lt;/span&gt;(instanceId, &lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;.Now);
                TheEvent(&lt;span style="color:blue;"&gt;null&lt;/span&gt;, args);
            }
        }
    }
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;And the event parameter looks like this:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;using &lt;/span&gt;System;
&lt;span style="color:blue;"&gt;using &lt;/span&gt;System.Workflow.Activities;

&lt;span style="color:blue;"&gt;namespace &lt;/span&gt;WorkflowLibrary1
{
    [&lt;span style="color:#2b91af;"&gt;Serializable&lt;/span&gt;]
    &lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;MyEventArgs &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;ExternalDataEventArgs
    &lt;/span&gt;{
        &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DateTime &lt;/span&gt;FiredAt { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }
        &lt;span style="color:blue;"&gt;public &lt;/span&gt;MyEventArgs(&lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;instanceId, &lt;span style="color:#2b91af;"&gt;DateTime &lt;/span&gt;firedAt)
            : &lt;span style="color:blue;"&gt;base&lt;/span&gt;(instanceId)
        {
            FiredAt = firedAt;
        }
    }
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Not much complexity there &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;.&lt;/p&gt;
&lt;p&gt;In the main function the workflow runtime is created and configured again. This time we also need to add the MyService as follows:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:#2b91af;"&gt;ExternalDataExchangeService &lt;/span&gt;edes = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExternalDataExchangeService&lt;/span&gt;();
workflowRuntime.AddService(edes);
&lt;span style="color:#2b91af;"&gt;MyService &lt;/span&gt;myService = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;MyService&lt;/span&gt;();
edes.AddService(myService);
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;The complete main function is at the bottom of the post but the most important things are the two Guids. The variable instanceId1 holds the WorkflowInstanceId from a workflow version 1.0.0.0 while the variable instanceId2 holds a WorkflowInstanceId from a workflow version 2.0.0.0. Both of these have been created during two previous runs and are saved by the SqlWorkflowPersistenceService added to the runtime. So lets see what happens when I run the application.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkflowspart2_5F00_DFB3/image_5F00_6.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="335" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkflowspart2_5F00_DFB3/image_5F00_thumb_5F00_2.png" width="672" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As we can see from the screenshot both workflows, the first in assembly 1.0.0.0 and the second in assembly 2.0.0.0, are running together&amp;nbsp; just fine. So lets see what happens when we raise the event TheEvent as declared in the external data exchange interface.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkflowspart2_5F00_DFB3/image_5F00_8.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="321" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkflowspart2_5F00_DFB3/image_5F00_thumb_5F00_3.png" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;As we can see from the screenshot above the second version of the workflow receives the event just fine but version 1.0.0.0 doesn&amp;#39;t and instead we receive the following exception:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Event &amp;quot;TheEvent&amp;quot; on interface type &amp;quot;WorkflowLibrary1.IMyService&amp;quot; for instance id &amp;quot;c9592a1b-e703-4726-b9bb-16410a7aaaad&amp;quot; cannot be delivered.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Now the workflow did manage to receive the event when it was just created, in fact it could up until the moment we recompiled the application and deployed version 2.0.0.0. Neither the workflow nor the service has changed so what gives?&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Underneath the covers of the HandleExternalEventActivity&lt;/h2&gt;
&lt;p&gt;To understand the problem we must first understand a bit more about the internals of the HandleExternalEventActivity. When we created the ExternalDataExchange interface we declared an event taking a parameter derived from ExternalDataEventArgs. And when configuring the HandleExternalEventActivity we specified an event name so everything works using .NET events right? Well no, wrong!&lt;/p&gt;
&lt;p&gt;In fact pretty much everything in Windows Workflow Foundation works based on queues. In fact due to the long running nature and the fact you don&amp;#39;t really know when thing will execute it must do so. In fact that is the reason why the event parameter must be marked with the Serializable attribute. In fact the ExternalDataExchangeService watches every for every possible event and converts every event into a queued message.&lt;/p&gt;
&lt;p&gt;Okay nice to know but how does that help with this problem?&lt;/p&gt;
&lt;p&gt;Well the thing is it needs to be able to find the correct queue to send the message and that is where things get interesting. When we look at WF queues we see that queue names are of type IComparable. Now most of the time when creating a queue the easiest thing to do is use a string or a guid as the queue name. And as both implement IComparable this is perfectly legal. But in the case of the ExternalDataExchangeService&amp;nbsp; and the HandleExternalEventActivity both need to be able to construct the same queue name based upon the interface and event name. And this is where the EventQueueName enters.&lt;/p&gt;
&lt;p&gt;The EventQueueName also implements IComparable and is used internally to uniquely identify a queue name. And when the EventQueueName checks if two queues are the same it doesn&amp;#39;t just use the interface name and the event name but it also compares the assemblies both are defined in. So in this case the workflow version 1.0.0.0 is creating a queue that contains the fact that it is from version 1.0.0.0 as part of the contract while the runtime only uses the last version this creating a queue that contains version 2.0.0.0 as part of the queue name.&lt;/p&gt;
&lt;p&gt;We can use the following code to pint the queue information from each workflow:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;static void &lt;/span&gt;PrintQueues(&lt;span style="color:#2b91af;"&gt;WorkflowRuntime &lt;/span&gt;workflowRuntime, &lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;instanceId)
{
    &lt;span style="color:#2b91af;"&gt;WorkflowInstance &lt;/span&gt;instance = workflowRuntime.GetWorkflow(instanceId);
    &lt;span style="color:#2b91af;"&gt;ReadOnlyCollection&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;WorkflowQueueInfo&lt;/span&gt;&amp;gt; queues = instance.GetWorkflowQueueData();
    &lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(&lt;span style="color:blue;"&gt;var &lt;/span&gt;queue &lt;span style="color:blue;"&gt;in &lt;/span&gt;queues)
    {
        &lt;span style="color:#2b91af;"&gt;EventQueueName &lt;/span&gt;queueName = queue.QueueName &lt;span style="color:blue;"&gt;as &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;EventQueueName&lt;/span&gt;;
        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(queueName != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
        {
            &lt;span style="color:#2b91af;"&gt;Assembly &lt;/span&gt;assembly = queueName.InterfaceType.Assembly;
            &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(queueName);
            &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(queueName.InterfaceType.Assembly.FullName);
            &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine();
        }
    }
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;With this as the result:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkflowspart2_5F00_DFB3/image_5F00_10.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="335" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkflowspart2_5F00_DFB3/image_5F00_thumb_5F00_4.png" width="672" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;The solution&lt;/h2&gt;
&lt;p&gt;The original function used raise the event looked like this:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;static void &lt;/span&gt;SendEvent1(&lt;span style="color:#2b91af;"&gt;WorkflowRuntime &lt;/span&gt;workflowRuntime, &lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;instanceId)
{
    &lt;span style="color:#2b91af;"&gt;MyService &lt;/span&gt;myService = workflowRuntime.GetService&amp;lt;&lt;span style="color:#2b91af;"&gt;MyService&lt;/span&gt;&amp;gt;();
    myService.OnTheEvent(instanceId);
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;The reason this is failing should now be apparent. After all the main program binds to the version of WorkflowLibrary1 it was build against or version 2.0.0.0. So the GetService() call returns a service object that created a queue name containing version 2.0.0.0 as part of its name and cannot call a HandleExternalEventActivity that creates a queue version 1.0.0.0.&lt;/p&gt;
&lt;p&gt;So the solution is to create the correct service object. Doing so isn&amp;#39;t complicated but does unfortunately requires some reflection because we need to work with the same type from an older assembly.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;static void &lt;/span&gt;SendEvent2(&lt;span style="color:#2b91af;"&gt;WorkflowRuntime &lt;/span&gt;workflowRuntime, &lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;instanceId)
{
    &lt;span style="color:#2b91af;"&gt;WorkflowInstance &lt;/span&gt;instance = workflowRuntime.GetWorkflow(instanceId);
    &lt;span style="color:#2b91af;"&gt;Assembly &lt;/span&gt;assembly = instance.GetWorkflowDefinition().GetType().Assembly;
    &lt;span style="color:#2b91af;"&gt;ExternalDataExchangeService &lt;/span&gt;edes = workflowRuntime.GetService&amp;lt;&lt;span style="color:#2b91af;"&gt;ExternalDataExchangeService&lt;/span&gt;&amp;gt;();
    &lt;span style="color:#2b91af;"&gt;Type &lt;/span&gt;type = assembly.GetType(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;MyService&lt;/span&gt;).FullName);
    &lt;span style="color:blue;"&gt;object &lt;/span&gt;myService = edes.GetService(type);

    &lt;span style="color:blue;"&gt;if &lt;/span&gt;(myService == &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
    {
        myService = &lt;span style="color:#2b91af;"&gt;Activator&lt;/span&gt;.CreateInstance(type);
        edes.AddService(myService);
    }

    &lt;span style="color:#2b91af;"&gt;MethodInfo &lt;/span&gt;mi = type.GetMethod(&lt;span style="color:#a31515;"&gt;&amp;quot;OnTheEvent&amp;quot;&lt;/span&gt;);
    mi.Invoke(myService, &lt;span style="color:blue;"&gt;new object&lt;/span&gt;[] { instanceId });
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;This code first gets an assembly reference to the assembly the actual workflow was defines in. Depending on the workflow this is either going to return assembly version 1.0.0.0 or version 2.0.0.0. Once we have this reference we retrieve the correct service type from the assembly. This type is different for each assembly so when we ask the ExternalDataExchangeService for the service it will try to return one with the correct type information. If this isn&amp;#39;t found yet it will return null and we can use the Activator.CreateInstance() to create the correct type adding it to the ExternalDataExchangeService for next time.&lt;/p&gt;
&lt;p&gt;Next we use reflection to execute the OnTheEvent we defined to fire the event for the workflow which now uses the correct version information when creating the queue name and everything works just fine.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkflowspart2_5F00_DFB3/image_5F00_12.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="321" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkflowspart2_5F00_DFB3/image_5F00_thumb_5F00_5.png" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;The screenshot above shows that both workflow versions are able to receive events again.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The code above works and solves the problem but is not very nice. It assumes that the ExternalDataExchange is defined in the same assembly as the workflow, something that doesn&amp;#39;t need to be the case. So is there a better solution? Yes but that is the subject of another blog post.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.theproblemsolver.nl/"&gt;www.TheProblemSolver.nl &lt;/a&gt;&lt;br /&gt;&lt;a href="http://wiki.windowsworkflowfoundation.eu/"&gt;Wiki.WindowsWorkflowFoundation.eu&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The complete main program:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;using &lt;/span&gt;System;
&lt;span style="color:blue;"&gt;using &lt;/span&gt;System.Workflow.Activities;
&lt;span style="color:blue;"&gt;using &lt;/span&gt;System.Workflow.Runtime;
&lt;span style="color:blue;"&gt;using &lt;/span&gt;System.Workflow.Runtime.Hosting;
&lt;span style="color:blue;"&gt;using &lt;/span&gt;WorkflowLibrary1;
&lt;span style="color:blue;"&gt;using &lt;/span&gt;System.Reflection;
&lt;span style="color:blue;"&gt;using &lt;/span&gt;System.Collections.ObjectModel;

&lt;span style="color:blue;"&gt;namespace &lt;/span&gt;WorkflowConsoleApplication1
{
    &lt;span style="color:blue;"&gt;class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Program
    &lt;/span&gt;{
        &lt;span style="color:blue;"&gt;static void &lt;/span&gt;Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)
        {
            &lt;span style="color:blue;"&gt;using &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;WorkflowRuntime &lt;/span&gt;workflowRuntime = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;WorkflowRuntime&lt;/span&gt;())
            {
                &lt;span style="color:#2b91af;"&gt;ExternalDataExchangeService &lt;/span&gt;edes = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExternalDataExchangeService&lt;/span&gt;();
                workflowRuntime.AddService(edes);
                &lt;span style="color:#2b91af;"&gt;MyService &lt;/span&gt;myService = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;MyService&lt;/span&gt;();
                edes.AddService(myService);

                &lt;span style="color:blue;"&gt;string &lt;/span&gt;connStr = &lt;span style="color:#a31515;"&gt;@&amp;quot;Data Source=.\sqlexpress;Initial Catalog=WorkflowPersistence;Integrated Security=True&amp;quot;&lt;/span&gt;;
                &lt;span style="color:#2b91af;"&gt;SqlWorkflowPersistenceService &lt;/span&gt;persistence = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;SqlWorkflowPersistenceService&lt;/span&gt;(connStr,
                    &lt;span style="color:blue;"&gt;true&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromSeconds(15), &lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromMinutes(1));
                workflowRuntime.AddService(persistence);

                workflowRuntime.ServicesExceptionNotHandled += (sender, e) =&amp;gt;
                    {
                        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(e.Exception.Message);
                    };

                workflowRuntime.StartRuntime();

                &lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;instanceId1 = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Guid&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;c9592a1b-e703-4726-b9bb-16410a7aaaad&amp;quot;&lt;/span&gt;);
                &lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;instanceId2 = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Guid&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;482e2742-e7c7-45e2-bcd3-8f894d200733&amp;quot;&lt;/span&gt;);


                &lt;span style="color:green;"&gt;//WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(Workflow1));
                //instanceId2 = instance.InstanceId;
                //instance.Start();


                &lt;/span&gt;&lt;span style="color:blue;"&gt;bool &lt;/span&gt;done = &lt;span style="color:blue;"&gt;false&lt;/span&gt;;
                &lt;span style="color:blue;"&gt;while &lt;/span&gt;(!done)
                {
                    &lt;span style="color:blue;"&gt;try
                    &lt;/span&gt;{
                        &lt;span style="color:#2b91af;"&gt;ConsoleKeyInfo &lt;/span&gt;key = &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.ReadKey(&lt;span style="color:blue;"&gt;true&lt;/span&gt;);
                        &lt;span style="color:blue;"&gt;switch &lt;/span&gt;(key.KeyChar)
                        {
                            &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#a31515;"&gt;&amp;#39;1&amp;#39;&lt;/span&gt;:
                                SendEvent2(workflowRuntime, instanceId1);
                                &lt;span style="color:blue;"&gt;break&lt;/span&gt;;

                            &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#a31515;"&gt;&amp;#39;2&amp;#39;&lt;/span&gt;:
                                SendEvent2(workflowRuntime, instanceId2);
                                &lt;span style="color:blue;"&gt;break&lt;/span&gt;;

                            &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#a31515;"&gt;&amp;#39;5&amp;#39;&lt;/span&gt;:
                                PrintQueues(workflowRuntime, instanceId1);
                                &lt;span style="color:blue;"&gt;break&lt;/span&gt;;

                            &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#a31515;"&gt;&amp;#39;6&amp;#39;&lt;/span&gt;:
                                PrintQueues(workflowRuntime, instanceId2);
                                &lt;span style="color:blue;"&gt;break&lt;/span&gt;;

                            &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#a31515;"&gt;&amp;#39;0&amp;#39;&lt;/span&gt;:
                                done = &lt;span style="color:blue;"&gt;true&lt;/span&gt;;
                                &lt;span style="color:blue;"&gt;break&lt;/span&gt;;
                        }
                    }
                    &lt;span style="color:blue;"&gt;catch &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;Exception &lt;/span&gt;ex)
                    {
                        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(ex.Message);
                    }
                }

                workflowRuntime.StopRuntime();
            }
        }

        &lt;span style="color:blue;"&gt;static void &lt;/span&gt;SendEvent1(&lt;span style="color:#2b91af;"&gt;WorkflowRuntime &lt;/span&gt;workflowRuntime, &lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;instanceId)
        {
            &lt;span style="color:#2b91af;"&gt;MyService &lt;/span&gt;myService = workflowRuntime.GetService&amp;lt;&lt;span style="color:#2b91af;"&gt;MyService&lt;/span&gt;&amp;gt;();
            myService.OnTheEvent(instanceId);
        }

        &lt;span style="color:blue;"&gt;static void &lt;/span&gt;SendEvent2(&lt;span style="color:#2b91af;"&gt;WorkflowRuntime &lt;/span&gt;workflowRuntime, &lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;instanceId)
        {
            &lt;span style="color:#2b91af;"&gt;WorkflowInstance &lt;/span&gt;instance = workflowRuntime.GetWorkflow(instanceId);
            &lt;span style="color:#2b91af;"&gt;Assembly &lt;/span&gt;assembly = instance.GetWorkflowDefinition().GetType().Assembly;
            &lt;span style="color:#2b91af;"&gt;ExternalDataExchangeService &lt;/span&gt;edes = workflowRuntime.GetService&amp;lt;&lt;span style="color:#2b91af;"&gt;ExternalDataExchangeService&lt;/span&gt;&amp;gt;();
            &lt;span style="color:#2b91af;"&gt;Type &lt;/span&gt;type = assembly.GetType(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;MyService&lt;/span&gt;).FullName);
            &lt;span style="color:blue;"&gt;object &lt;/span&gt;myService = edes.GetService(type);

            &lt;span style="color:blue;"&gt;if &lt;/span&gt;(myService == &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
            {
                myService = &lt;span style="color:#2b91af;"&gt;Activator&lt;/span&gt;.CreateInstance(type);
                edes.AddService(myService);
            }

            &lt;span style="color:#2b91af;"&gt;MethodInfo &lt;/span&gt;mi = type.GetMethod(&lt;span style="color:#a31515;"&gt;&amp;quot;OnTheEvent&amp;quot;&lt;/span&gt;);
            mi.Invoke(myService, &lt;span style="color:blue;"&gt;new object&lt;/span&gt;[] { instanceId });
        }

        &lt;span style="color:blue;"&gt;static void &lt;/span&gt;PrintQueues(&lt;span style="color:#2b91af;"&gt;WorkflowRuntime &lt;/span&gt;workflowRuntime, &lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;instanceId)
        {
            &lt;span style="color:#2b91af;"&gt;WorkflowInstance &lt;/span&gt;instance = workflowRuntime.GetWorkflow(instanceId);
            &lt;span style="color:#2b91af;"&gt;ReadOnlyCollection&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;WorkflowQueueInfo&lt;/span&gt;&amp;gt; queues = instance.GetWorkflowQueueData();
            &lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(&lt;span style="color:blue;"&gt;var &lt;/span&gt;queue &lt;span style="color:blue;"&gt;in &lt;/span&gt;queues)
            {
                &lt;span style="color:#2b91af;"&gt;EventQueueName &lt;/span&gt;queueName = queue.QueueName &lt;span style="color:blue;"&gt;as &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;EventQueueName&lt;/span&gt;;
                &lt;span style="color:blue;"&gt;if &lt;/span&gt;(queueName != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
                {
                    &lt;span style="color:#2b91af;"&gt;Assembly &lt;/span&gt;assembly = queueName.InterfaceType.Assembly;
                    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(queueName);
                    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(queueName.InterfaceType.Assembly.FullName);
                    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine();
                }
            }
        }
    }
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1647516" width="1" height="1"&gt;</content><author><name>Maurice</name><uri>http://msmvps.com/members/Maurice/default.aspx</uri></author><category term=".NET" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/.NET/default.aspx" /><category term="NetFx3" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/NetFx3/default.aspx" /><category term="Workflow" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/Workflow/default.aspx" /><category term="VB" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/VB/default.aspx" /><category term="DevCenter" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/DevCenter/default.aspx" /></entry><entry><title>Versioning long running workfows part 1</title><link rel="alternate" type="text/html" href="/blogs/theproblemsolver/archive/2008/09/10/versioning-long-running-workfows.aspx" /><id>/blogs/theproblemsolver/archive/2008/09/10/versioning-long-running-workfows.aspx</id><published>2008-09-10T10:46:03Z</published><updated>2008-09-10T10:46:03Z</updated><content type="html">&lt;p&gt;Part 1&lt;br /&gt;Part 2&lt;br /&gt;Part 3&lt;br /&gt;Part 4  &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;One of the cool features of Windows Workflow Foundation is that it allows long&amp;nbsp; running processes. And not just long running as in a few minutes but really long running as in a few years &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;. This is possible true the use of the SqlWorkflowPersistenceService, or in fact any derived class from WorkflowPersistenceService, which is going to save the state of a workflow to disk when it is not actually busy.&lt;/p&gt; &lt;p&gt;So that is pretty cool but it is kind of unlikely that your programs are not going to change over a year so in all likelihood&amp;nbsp; you are going to be deploying newer versions of your assemblies while there are multiple workflow&amp;#39;s active. In order to allow multiple versions of a workflow to run we need to understand what is going on under the covers.&lt;/p&gt; &lt;p&gt;To demonstrate the behavior I am going to use a small project with the following layout. The WorkflowConsoleApplication1 is the host and is configured to use SqlWorkflowPersistenceService. The WorkflowLibrary1 is the project containing the actual workflow and this is the project we are going to version.&lt;/p&gt; &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfows_5F00_A4EE/image_5F00_8.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="220" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfows_5F00_A4EE/image_5F00_thumb_5F00_3.png" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;The main program is pretty simple and looks like this:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;static void &lt;/span&gt;Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)
{
    &lt;span style="color:blue;"&gt;using &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;WorkflowRuntime &lt;/span&gt;workflowRuntime = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;WorkflowRuntime&lt;/span&gt;())
    {

        &lt;span style="color:blue;"&gt;string &lt;/span&gt;connStr = &lt;span style="color:#a31515;"&gt;@&amp;quot;Data Source=.\sqlexpress;Initial Catalog=WorkflowPersistence;Integrated Security=True&amp;quot;&lt;/span&gt;;
        &lt;span style="color:#2b91af;"&gt;SqlWorkflowPersistenceService &lt;/span&gt;persistence = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;SqlWorkflowPersistenceService&lt;/span&gt;(connStr,
            &lt;span style="color:blue;"&gt;true&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromSeconds(15), &lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromMinutes(1));
        workflowRuntime.AddService(persistence);

        workflowRuntime.ServicesExceptionNotHandled += (sender, e) =&amp;gt;
            {
                &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(e.Exception.Message);
            };

        workflowRuntime.StartRuntime();

        &lt;span style="color:#2b91af;"&gt;WorkflowInstance &lt;/span&gt;instance = workflowRuntime.CreateWorkflow(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;Workflow1&lt;/span&gt;));
        instance.Start();



        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Press ennter to stop&amp;quot;&lt;/span&gt;);
        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.ReadLine();

        workflowRuntime.StopRuntime();
    }
}&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Basically it sets up the SqlWorkflowPersistenceService, starts the runtime, starts a new workflow and waits for the user to terminate the program. It also prints any exceptions that might occur in a workflow runtime service like the SqlWorkflowPersistenceService.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfows_5F00_A4EE/image_5F00_12.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="278" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfows_5F00_A4EE/image_5F00_thumb_5F00_5.png" width="304" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;The workflow is real simple. It just loops forever and prints a message that includes the assembly version number every 10 seconds.&lt;/p&gt;
&lt;p&gt;What we are going to do is start this program so we have a first instance in the persistence store, update the workflow assembly to version two an have version 1 and 2 run side by side.&lt;/p&gt;
&lt;h2&gt;The WorkflowPersistenceService part.&lt;/h2&gt;
&lt;p&gt;The WorkflowPersistenceService actually persists, or dehydrates as it is called, a workflow using the binary serializer. This means that when it recreates, or dehydrates as this is called, the workflow instance it is done in a assembly version depended manner. So the first thing to be aware of is the standard .NET versioning behavior.&lt;/p&gt;
&lt;p&gt;For a .NET assembly to be versionable the first prerequisite is that it has a string name. The rules are simple, no strong name = no versioning and the first assembly found will be the one that is used. Now there is a potential problem here because the binary serializer uses the most compact form possible and doesn&amp;#39;t store field names, only their value. The object is responsible for reading the data from a stream in the correct order and size. No problem as long as the same type that was serialized is actually used to deserialize an object. But suppose a newer type is used that actually expects extra fields? Well it is going to try to read some data that is not actually there and the process is going to fail &lt;img src="http://msmvps.com/emoticons/emotion-6.gif" alt="Sad" /&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Versioning assemblies is important!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So in order to be able to version the WorkflowLibrary1 assembly we need to add a strong name. This is done in the project settings on the Signing tab as follows:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfows_5F00_A4EE/image_5F00_10.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="275" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfows_5F00_A4EE/image_5F00_thumb_5F00_4.png" width="483" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;When we run the application we can see from the following output that the workflow version 1 is running just fine &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfows_5F00_A4EE/image_5F00_2.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="248" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfows_5F00_A4EE/image_5F00_thumb.png" width="496" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Once we have stopped the application its time to upgrade to version 2.0.0.0. Now I am not even going to make any changes to the workflow, all I am going to do is change the assembly major version number of the WorkflowLibrary1 project to 2. This is actually stored as part of the assembly and thus causes the project to recompile.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfows_5F00_A4EE/image_5F00_4.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="312" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfows_5F00_A4EE/image_5F00_thumb_5F00_1.png" width="327" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;If we run the application again we are going to see the following output:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfows_5F00_A4EE/image_5F00_6.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="246" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfows_5F00_A4EE/image_5F00_thumb_5F00_2.png" width="491" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;While version 2.0.0.0 of the workflow will run just fine version 1.0.0.0 cannot be loaded and the SqlWorkflowPersistenceService reports the following error via the WorkflowRuntime ServicesExceptionNotHandled event.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Could not load file or assembly &amp;#39;WorkflowLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8afb6d596a769080&amp;#39; or one of its dependencies. The located assembly&amp;#39;s manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;This error is the result of the binary serializer seeing that the workflow was dehydrated with version 1.0.0.0 of the WorkflowLibrary1 so it wants to load that version. And that is nowhere to be found as we only have version 2.0.0.0 which is not good enough.&lt;/p&gt;
&lt;h2&gt;Enabling side by side execution&lt;/h2&gt;
&lt;p&gt;The first ting we need to do is make sure we have both versions of the assembly WorkflowLibrary1 available. In order to do so we need to create a folder in the bin\Debug folder with the name Version_1_0_0_0. This is the folder where I am going to keep a copy of the WorkflowLibrary1.dll version 1.0.0.0.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfows_5F00_A4EE/image_5F00_16.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="92" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfows_5F00_A4EE/image_5F00_thumb_5F00_7.png" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Next we need to tell the .NET runtime where to look for version 1.0.0.0 of the assembly by adding this information to the app.config of our application. This is standard .NET material and in no way specific to Windows Workflow Foundation. The app.config looks like this:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color:#a31515;"&gt;xml &lt;/span&gt;&lt;span style="color:red;"&gt;version&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;1.0&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;encoding&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;utf-8&lt;/span&gt;&amp;quot; &lt;span style="color:blue;"&gt;?&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;configuration&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;runtime&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;assemblyBinding &lt;/span&gt;&lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;urn:schemas-microsoft-com:asm.v1&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;dependentAssembly&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;assemblyIdentity &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;WorkflowLibrary1&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;publicKeyToken&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;8afb6d596a769080&lt;/span&gt;&amp;quot; &lt;span style="color:blue;"&gt;/&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;codeBase &lt;/span&gt;&lt;span style="color:red;"&gt;version&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;1.0.0.0&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;href&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;Version_1_0_0_0/WorkflowLibrary1.dll&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;
      &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;dependentAssembly&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;assemblyBinding&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;runtime&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;configuration&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;With both versions of the assembly and configuring the runtime so it knows where to find the first version of the assembly both versions of the workflow will run happily together &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfows_5F00_A4EE/image_5F00_18.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="254" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.Versioninglongrunningworkfows_5F00_A4EE/image_5F00_thumb_5F00_8.png" width="508" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;So how about the GAC?&lt;/h2&gt;
&lt;p&gt;In this example I use a private location to store multiple versions of the assembly but I could also have used the Global Assembly Cache, of GAC for short, to do this. Both mechanisms allow an assembly to be versioned so which is better? Normally the GAC should be used by assemblies used with multiple applications. In this case, and this is probably the case with most workflow assemblies, the WorkflowLibrary1 assembly only used by our host and not by other applications making a private location the proper place. That said there are certainly scenarios, like shared custom activity assemblies, where the GAC would be the proper place.&lt;/p&gt;
&lt;h2&gt;So are we all set?&lt;/h2&gt;
&lt;p&gt;No unfortunately not quite because there are some more issues that might crop up with versioning. So stay tuned for more &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.theproblemsolver.nl/"&gt;www.TheProblemSolver.nl &lt;/a&gt;&lt;br /&gt;&lt;a href="http://wiki.windowsworkflowfoundation.eu/"&gt;Wiki.WindowsWorkflowFoundation.eu&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1647324" width="1" height="1"&gt;</content><author><name>Maurice</name><uri>http://msmvps.com/members/Maurice/default.aspx</uri></author><category term=".NET" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/.NET/default.aspx" /><category term="NetFx3" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/NetFx3/default.aspx" /><category term="Workflow" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/Workflow/default.aspx" /><category term="VB" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/VB/default.aspx" /><category term="DevCenter" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/DevCenter/default.aspx" /></entry><entry><title>Changing a Declarative Rule Condition at runtime</title><link rel="alternate" type="text/html" href="/blogs/theproblemsolver/archive/2008/09/04/changing-a-declarative-rule-condition-at-runtime.aspx" /><id>/blogs/theproblemsolver/archive/2008/09/04/changing-a-declarative-rule-condition-at-runtime.aspx</id><published>2008-09-04T19:27:39Z</published><updated>2008-09-04T19:27:39Z</updated><content type="html">&lt;p&gt;One powerful feature of a workflow is that a workflow can be changed at runtime. Like other powerful features this is something that should be done with care but it can be a real life saver at times.&lt;/p&gt; &lt;p&gt;One of the things that you can change are Declarative Rule Conditions. However as these rules are really CodeDom objects it can be a bit tricky to find the right property to change. However once you know a little tick life is much easier. &lt;/p&gt; &lt;p&gt;The trick is in the .rules file created when you add a Declarative Rule Condition to the workflow and is best demonstrated using a small example. Take the following workflow:&lt;/p&gt; &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.ChangingaDeclarativeRuleConditionatrunti_5F00_F69E/image_5F00_2.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="273" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.ChangingaDeclarativeRuleConditionatrunti_5F00_F69E/image_5F00_thumb.png" width="317" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;The IfElseActivity has a Declarative Rule Condition which looks like this:&lt;/p&gt; &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.ChangingaDeclarativeRuleConditionatrunti_5F00_F69E/image_5F00_4.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="187" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.ChangingaDeclarativeRuleConditionatrunti_5F00_F69E/image_5F00_thumb_5F00_1.png" width="377" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;So I consider every amount larger that 100 large. Hmm not much, lets change that to 1000 instead of 100 &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;&lt;/p&gt; &lt;p&gt;The first step is we need to change the workflow instance so we need a WorkflowChanges object passing in the workflow root as the activity. No big deal but what now. Well lets open the Workflow1.Rules file and take a look at what is inside.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;RuleDefinitions &lt;/span&gt;&lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;http://schemas.microsoft.com/winfx/2006/xaml/workflow&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;RuleDefinitions.Conditions&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;RuleExpressionCondition &lt;/span&gt;&lt;span style="color:red;"&gt;Name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;LargeAmountRule&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;RuleExpressionCondition.Expression&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ns0:CodeBinaryOperatorExpression &lt;/span&gt;&lt;span style="color:red;"&gt;Operator&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;GreaterThan&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;xmlns:ns0&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;clr-namespace:System.CodeDom;Assembly=System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ns0:CodeBinaryOperatorExpression.Left&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
                        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ns0:CodePropertyReferenceExpression &lt;/span&gt;&lt;span style="color:red;"&gt;PropertyName&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;Amount&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;
                            &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ns0:CodePropertyReferenceExpression.TargetObject&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
                                &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ns0:CodeThisReferenceExpression &lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;
                            &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ns0:CodePropertyReferenceExpression.TargetObject&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
                        &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ns0:CodePropertyReferenceExpression&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
                    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ns0:CodeBinaryOperatorExpression.Left&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ns0:CodeBinaryOperatorExpression.Right&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
                        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ns0:CodePrimitiveExpression&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
                            &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ns0:CodePrimitiveExpression.Value&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
                                &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ns1:Int32 &lt;/span&gt;&lt;span style="color:red;"&gt;xmlns:ns1&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;100&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ns1:Int32&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
                            &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ns0:CodePrimitiveExpression.Value&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
                        &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ns0:CodePrimitiveExpression&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
                    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ns0:CodeBinaryOperatorExpression.Right&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
                &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ns0:CodeBinaryOperatorExpression&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
            &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;RuleExpressionCondition.Expression&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;RuleExpressionCondition&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;RuleDefinitions.Conditions&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;RuleDefinitions&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;It turns out that the XML is a very literal representation of the objects that make up our rule and what we need to change. So we need to start with a RuleDefinitions.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:#2b91af;"&gt;RuleDefinitions &lt;/span&gt;rules =
    (&lt;span style="color:#2b91af;"&gt;RuleDefinitions&lt;/span&gt;)changes.TransientWorkflow.GetValue(&lt;span style="color:#2b91af;"&gt;RuleDefinitions&lt;/span&gt;.RuleDefinitionsProperty);
&lt;/pre&gt;
&lt;p&gt;So getting our hand on it is easy, just use the GetValue function passing in the RuleDefinitionsProperty dependency property.&lt;/p&gt;
&lt;p&gt;Once we have this things are even easier as it is just following the XML &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;. It shows the RuleDefinitions object has a Conditions property and our rule is in there with a name LargeAmountRule and is of type RuleExpressionCondition. This rule in turn contains a left and right part with the right part pointing at the value of 100 we want to change. Again this value is of a type CodePrimitiveExpression, another easy cast. The code below is the complete code required to change the value from 100 to1000.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:#2b91af;"&gt;WorkflowChanges &lt;/span&gt;changes = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;WorkflowChanges&lt;/span&gt;(&lt;span style="color:blue;"&gt;this&lt;/span&gt;);

&lt;span style="color:#2b91af;"&gt;RuleDefinitions &lt;/span&gt;rules =
    (&lt;span style="color:#2b91af;"&gt;RuleDefinitions&lt;/span&gt;)changes.TransientWorkflow.GetValue(&lt;span style="color:#2b91af;"&gt;RuleDefinitions&lt;/span&gt;.RuleDefinitionsProperty);

&lt;span style="color:#2b91af;"&gt;RuleExpressionCondition &lt;/span&gt;rule = (&lt;span style="color:#2b91af;"&gt;RuleExpressionCondition&lt;/span&gt;)rules.Conditions
    .First(rc =&amp;gt; rc.Name == &lt;span style="color:#a31515;"&gt;&amp;quot;LargeAmountRule&amp;quot;&lt;/span&gt;);
&lt;span style="color:#2b91af;"&gt;CodeBinaryOperatorExpression &lt;/span&gt;expression = (&lt;span style="color:#2b91af;"&gt;CodeBinaryOperatorExpression&lt;/span&gt;)rule.Expression;
&lt;span style="color:#2b91af;"&gt;CodePrimitiveExpression &lt;/span&gt;primitive = (&lt;span style="color:#2b91af;"&gt;CodePrimitiveExpression&lt;/span&gt;)expression.Right;
primitive.Value = 1000;

ApplyWorkflowChanges(changes);
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Easy once you know where to look &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.theproblemsolver.nl/"&gt;www.TheProblemSolver.nl &lt;/a&gt;&lt;br /&gt;&lt;a href="http://wiki.windowsworkflowfoundation.eu/"&gt;Wiki.WindowsWorkflowFoundation.eu&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1646799" width="1" height="1"&gt;</content><author><name>Maurice</name><uri>http://msmvps.com/members/Maurice/default.aspx</uri></author><category term=".NET" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/.NET/default.aspx" /><category term="NetFx3" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/NetFx3/default.aspx" /><category term="Workflow" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/Workflow/default.aspx" /><category term="DevCenter" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/DevCenter/default.aspx" /></entry><entry><title>Calling WCF services from a Silverlight 2 app.</title><link rel="alternate" type="text/html" href="/blogs/theproblemsolver/archive/2008/08/26/calling-wcf-services-from-a-silverlight-2-app.aspx" /><id>/blogs/theproblemsolver/archive/2008/08/26/calling-wcf-services-from-a-silverlight-2-app.aspx</id><published>2008-08-25T22:11:00Z</published><updated>2008-08-25T22:11:00Z</updated><content type="html">&lt;p&gt;As far as I am concerned Silverlight 2 is pretty cool and should have been developed years ago &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;. Well guess that isn&amp;#39;t the case but it is here now.&lt;/p&gt;
&lt;p&gt;One thing I like about Silverlight is how easy it is to call a web service. I guess that is a must be because when developing a LOB application in Silverlight you are going to be calling your server to get and store data. So calling the back end is as easy as adding a new Silverlight-enabled WCF Service, implementing the ServiceContract and setting a service reference from your Silverlight project. Things will work immediately and you are all good to go.&lt;/p&gt;
&lt;h2&gt;Or maybe not &lt;img src="http://msmvps.com/emoticons/emotion-6.gif" alt="Sad" /&gt;&lt;/h2&gt;
&lt;p&gt;Well your service will work just fine in your development machine, no problems there. But when you move your project to another machine thing might just stop working and you will see a ProtocolException with message &amp;quot;The remote server returned an unexpected response: (404) Not Found.&amp;quot;. &lt;/p&gt;
&lt;p&gt;So what gives?&lt;/p&gt;
&lt;p&gt;Well the problem is that the WCF stores the absolute Uri for the WCF service in its configuration file, the ServiceReferences.ClientConfig. In this case the configuration looks like this:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;configuration&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bindings&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;basicHttpBinding&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;binding &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;BasicHttpBinding_Service&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;maxBufferSize&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;65536&lt;/span&gt;&amp;quot;
                    &lt;span style="color:red;"&gt;maxReceivedMessageSize&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;65536&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;security &lt;/span&gt;&lt;span style="color:red;"&gt;mode&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;None&lt;/span&gt;&amp;quot; &lt;span style="color:blue;"&gt;/&amp;gt;
                &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;binding&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
            &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;basicHttpBinding&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bindings&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;client&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;endpoint &lt;/span&gt;&lt;span style="color:red;"&gt;address&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;http://localhost:4370/SilverlightApplication3Web/Service.svc&lt;/span&gt;&amp;quot;
                &lt;span style="color:red;"&gt;binding&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;basicHttpBinding&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;bindingConfiguration&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;BasicHttpBinding_Service&lt;/span&gt;&amp;quot;
                &lt;span style="color:red;"&gt;contract&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;SilverlightApplication3.ServiceReference1.Service&lt;/span&gt;&amp;quot;
                &lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;BasicHttpBinding_Service.&lt;/span&gt;&amp;quot; &lt;span style="color:blue;"&gt;/&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;client&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;configuration&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The problem here is the endpoint address that points to localhost port 4370. So as this service is part of the same website using a relative Uri sounds like the reasonable thing to do. Unfortunately this doesn&amp;#39;t work and results in an UriFormatException with message: &amp;quot;Invalid URI: The format of the URI could not be determined.&amp;quot;. Not good. So this means we have to change the address for every local endpoint when we move the Silverlight application, and its WCF services, to a different location. Not good, specially when we could have a long list of services used &lt;img src="http://msmvps.com/emoticons/emotion-6.gif" alt="Sad" /&gt;.&lt;/p&gt;
&lt;h2&gt;A partial solution&lt;/h2&gt;
&lt;p&gt;So fortunately there is a way around this as we can specify the service address when creating the WCF service proxy, all we need to do is insert the correct Uri based upon the location of the Silverlight application.&lt;/p&gt;
&lt;p&gt;Normally the code I write looks something like this:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:#2b91af;"&gt;ServiceClient &lt;/span&gt;proxy = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ServiceClient&lt;/span&gt;();
proxy.DoWorkCompleted += proxy_DoWorkCompleted;
proxy.DoWorkAsync();
&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;What I need to do is change this somewhat so that the ServiceClient is created through a factory method like this:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:#2b91af;"&gt;ServiceClient &lt;/span&gt;proxy = GetServiceClient();
proxy.DoWorkCompleted += proxy_DoWorkCompleted;
proxy.DoWorkAsync();
&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The interesting work occurs in the GetServiceClient() function:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ServiceClient &lt;/span&gt;GetServiceClient()
{
    &lt;span style="color:#2b91af;"&gt;Uri &lt;/span&gt;uri = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Uri&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;HtmlPage&lt;/span&gt;.Document.DocumentUri, &lt;span style="color:#a31515;"&gt;&amp;quot;Service.svc&amp;quot;&lt;/span&gt;);
    &lt;span style="color:#2b91af;"&gt;EndpointAddress &lt;/span&gt;address = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;EndpointAddress&lt;/span&gt;(uri);

    &lt;span style="color:blue;"&gt;return new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ServiceClient&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;*&amp;quot;&lt;/span&gt;, address);
}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;First I determine where the Silverlight application was loaded from in the first place through the HtmlPage.Document.DocumentUri. Next I create a new Uri with the relative address where the service should be located. And finally I create and return the WCF proxy object. The first parameter, the&amp;nbsp; &lt;span style="color:#a31515;"&gt;&amp;quot;*&amp;quot; &lt;/span&gt;indicated that the WCF runtime should use a wildcard match and the first endpoint found with the same contract, which is the same as when no parameters are passed in.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;A better solution&lt;/h2&gt;
&lt;p&gt;Of course the solution above works but requires extra coding and care with every service we create. And being easy to forget, specially when you just get started with Silverlight, is not exactly an ideal solution. So the proper solution is that the WCF stack inside of Silverlight should accept relative Uri and understand that this Uri is relative to the current page. Now this is not exactly rocket science and exactly what browsers have been doing for years. So lets hope the Silverlight team adds this feature before the RTM (which I hope is real soon).&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.theproblemsolver.nl/"&gt;www.TheProblemSolver.nl &lt;/a&gt;&lt;br /&gt;&lt;a href="http://wiki.windowsworkflowfoundation.eu/"&gt;Wiki.WindowsWorkflowFoundation.eu&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1645795" width="1" height="1"&gt;</content><author><name>Maurice</name><uri>http://msmvps.com/members/Maurice/default.aspx</uri></author><category term=".NET" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/.NET/default.aspx" /><category term="NetFx3" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/NetFx3/default.aspx" /><category term="WCF" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/WCF/default.aspx" /><category term="DevCenter" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/DevCenter/default.aspx" /><category term="Silverlight" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/Silverlight/default.aspx" /></entry><entry><title>Using an IronPython runtime service from Windows Workflow Foundation</title><link rel="alternate" type="text/html" href="/blogs/theproblemsolver/archive/2008/08/25/using-an-ironpython-runtime-service-from-windows-workflow-foundation.aspx" /><id>/blogs/theproblemsolver/archive/2008/08/25/using-an-ironpython-runtime-service-from-windows-workflow-foundation.aspx</id><published>2008-08-25T10:15:18Z</published><updated>2008-08-25T10:15:18Z</updated><content type="html">&lt;p&gt;In &lt;a href="http://msmvps.com/blogs/theproblemsolver/archive/2008/08/14/calling-ironpython-functions-from-net.aspx"&gt;this post&lt;/a&gt; I demonstrated how to create &lt;a href="http://www.codeplex.com/IronPython"&gt;IronPython&lt;/a&gt; objects and call them from strongly typed .NET code. So suppose we want to do so with &lt;a href="http://wiki.windowsworkflowfoundation.eu/default.aspx/WF/Workflow%20Foundation.html"&gt;Windows Workflow Foundation&lt;/a&gt; where could we use this?&lt;/p&gt; &lt;p&gt;Well the most obvious place would be a &lt;a href="http://wiki.windowsworkflowfoundation.eu/default.aspx/WF/WorkflowRuntimeService.html"&gt;runtime service&lt;/a&gt;. The example below uses a very simple message that needs to be displayed but it is easy to see how to same concept could be applied in other places.&lt;/p&gt; &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.UsinganIronPythonruntimeservicefromWindo_5F00_A4C6/image_5F00_2.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="337" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.UsinganIronPythonruntimeservicefromWindo_5F00_A4C6/image_5F00_thumb.png" width="541" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;But first the basics. I have created a very simple custom DisplayMessageActivity like this:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public partial class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DisplayMessageActivity &lt;/span&gt;: System.Workflow.ComponentModel.&lt;span style="color:#2b91af;"&gt;Activity
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;DisplayMessageActivity()
    {
    }

    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;Message { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;protected override &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ActivityExecutionStatus &lt;/span&gt;Execute(
        &lt;span style="color:#2b91af;"&gt;ActivityExecutionContext &lt;/span&gt;executionContext)
    {
        &lt;span style="color:#2b91af;"&gt;IDisplayMessageService &lt;/span&gt;service = executionContext.GetService&amp;lt;&lt;span style="color:#2b91af;"&gt;IDisplayMessageService&lt;/span&gt;&amp;gt;();
        service.Display(Message);

        &lt;span style="color:blue;"&gt;return base&lt;/span&gt;.Execute(executionContext);
    }
}
&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Next I have created a very simple workflow with only the DisplayMessageActivity and set the Message property to: &amp;quot;This is the message to show.&amp;quot;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;You might have noticed in the code above that I am looking for a service of type &lt;span style="color:#2b91af;"&gt;IDisplayMessageService&lt;/span&gt;. This is pretty simple as well and looks like this:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public interface &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IDisplayMessageService
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;void &lt;/span&gt;Display(&lt;span style="color:blue;"&gt;string &lt;/span&gt;message);
}
&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;In this case I am using an interface but you could just as well use a concrete baseclass with virtual methods.&lt;/p&gt;
&lt;p&gt;For the actual implementation I created two classes in IronPython, the first displays the message on the console while the second uses a MessageBox to display the same message. The IronPython source looks like this:&lt;/p&gt;&lt;pre class="code"&gt;import clr

clr.AddReference(&amp;#39;PythonWorkflowConsoleApplication1&amp;#39;)
from PythonWorkflowConsoleApplication1 import IDisplayMessageService

clr.AddReference(&amp;quot;System.Windows.Forms&amp;quot;)
from System.Windows.Forms import MessageBox

# Display all messages in the console window
class ConsoleDisplayMessageService(IDisplayMessageService):
    def Display(self, message):
        print message

# Display all messages using a Windows.Forms.MessageBox
class MessageBoxDisplayMessageService(IDisplayMessageService):
    def Display(self, message):
        MessageBox.Show(message, &amp;#39;IronPython&amp;#39;)
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Like in the previous example I first import the clr so I can set references to additional assemblies. Next add a reference to the PythonWorkflowConsoleApplication1 assembly. This is my sample application that contains the runtime service interface definition. With this reference set I can import the IDisplayMessageService interface so I can derive from it. &lt;/p&gt;
&lt;p&gt;I included two implementations, lets first look at the ConsoleDisplayMessageService as this is the simpler of the two. All this does is use the Python print function to display the message on the console. The first parameter, self, is the current object, so this in C# or me in VB. We make sure this class derives from IDisplayMessageService by specifying this after the class name. BTW the lines starting with # are comments in Python.&lt;/p&gt;
&lt;p&gt;The second class is MessageBoxDisplayMessageService and this actually uses a MessageBox to display the message from the workflow. First we need to add a reference to the System.Windows.Forms assembly and once that is done we need to import the MessageBox type. Once this is done we can use it like this: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MessageBox.Show(message, &amp;#39;IronPython&amp;#39;)&lt;/p&gt;
&lt;p&gt;Simple enough right.&lt;/p&gt;
&lt;p&gt;So now for the trick part, adding the IronPython runtime service to the workflow runtime.&lt;/p&gt;
&lt;p&gt;The console main function is as follows:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;static void &lt;/span&gt;Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)
{
    &lt;span style="color:blue;"&gt;using &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;WorkflowRuntime &lt;/span&gt;workflowRuntime = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;WorkflowRuntime&lt;/span&gt;())
    {
        AddMessageService(workflowRuntime, &lt;span style="color:#2b91af;"&gt;DisplayMode&lt;/span&gt;.Windows);

        &lt;span style="color:#2b91af;"&gt;WorkflowInstance &lt;/span&gt;instance = workflowRuntime.CreateWorkflow(
            &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(PythonWorkflowConsoleApplication1.&lt;span style="color:#2b91af;"&gt;Workflow1&lt;/span&gt;));
        instance.Start();

        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.ReadLine();
    }
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;With the AddMessageService() doing the actual work. Note the second parameter specifies which IronPython class to load.&lt;/p&gt;
&lt;p&gt;So the AddMessageService looks like this:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;static void &lt;/span&gt;AddMessageService(&lt;span style="color:#2b91af;"&gt;WorkflowRuntime &lt;/span&gt;workflowRuntime, &lt;span style="color:#2b91af;"&gt;DisplayMode &lt;/span&gt;mode)
{
    &lt;span style="color:blue;"&gt;string &lt;/span&gt;className;
    &lt;span style="color:blue;"&gt;if &lt;/span&gt;(mode == &lt;span style="color:#2b91af;"&gt;DisplayMode&lt;/span&gt;.Console)
        className = &lt;span style="color:#a31515;"&gt;&amp;quot;ConsoleDisplayMessageService&amp;quot;&lt;/span&gt;;
    &lt;span style="color:blue;"&gt;else
        &lt;/span&gt;className = &lt;span style="color:#a31515;"&gt;&amp;quot;MessageBoxDisplayMessageService&amp;quot;&lt;/span&gt;;

    &lt;span style="color:#2b91af;"&gt;ScriptRuntime &lt;/span&gt;runtime = &lt;span style="color:#2b91af;"&gt;PythonEngine&lt;/span&gt;.CurrentEngine.Runtime;
    &lt;span style="color:#2b91af;"&gt;ScriptScope &lt;/span&gt;scope = runtime.ExecuteFile(&lt;span style="color:#a31515;"&gt;&amp;quot;DisplayMessageService.py&amp;quot;&lt;/span&gt;);

    &lt;span style="color:#2b91af;"&gt;PythonType &lt;/span&gt;pythonType = scope.GetVariable&amp;lt;&lt;span style="color:#2b91af;"&gt;PythonType&lt;/span&gt;&amp;gt;(className);
    &lt;span style="color:blue;"&gt;object &lt;/span&gt;service = runtime.Operations.Call(pythonType);

    workflowRuntime.AddService(service);
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;The basics are the same as in my &lt;a href="http://msmvps.com/blogs/theproblemsolver/archive/2008/08/14/calling-ironpython-functions-from-net.aspx"&gt;previous&lt;/a&gt; IronPython post. Depending on the display mode I make a choice of class to load and I use the same code as previous time to create the object. Finally I add it to the &lt;a href="http://wiki.windowsworkflowfoundation.eu/default.aspx/WF/WorkflowRuntime.html"&gt;WorkflowRuntime&lt;/a&gt; as a &lt;a href="http://wiki.windowsworkflowfoundation.eu/default.aspx/WF/WorkflowRuntimeService.html"&gt;runtime service&lt;/a&gt;. This last bit is easy as this accepts every object type as a valid service and only when we call the GetService do we check the actual type.&lt;/p&gt;
&lt;p&gt;I used IronPython 2.0 Beta 4 for this example. More info about IronPython can be found &lt;a href="http://www.codeplex.com/IronPython"&gt;here&lt;/a&gt;, the download of version 2 &lt;a href="http://www.codeplex.com/IronPython/Release/ProjectReleases.aspx?ReleaseId=14353"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.theproblemsolver.nl/"&gt;www.TheProblemSolver.nl &lt;/a&gt;&lt;br /&gt;&lt;a href="http://wiki.windowsworkflowfoundation.eu/"&gt;Wiki.WindowsWorkflowFoundation.eu&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1645704" width="1" height="1"&gt;</content><author><name>Maurice</name><uri>http://msmvps.com/members/Maurice/default.aspx</uri></author><category term=".NET" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/.NET/default.aspx" /><category term="NetFx3" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/NetFx3/default.aspx" /><category term="Workflow" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/Workflow/default.aspx" /><category term="DevCenter" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/DevCenter/default.aspx" /><category term="IronPython" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/IronPython/default.aspx" /></entry><entry><title>Red Gate to continue development of .NET Reflector</title><link rel="alternate" type="text/html" href="/blogs/theproblemsolver/archive/2008/08/20/red-gate-to-continue-development-of-net-reflector.aspx" /><id>/blogs/theproblemsolver/archive/2008/08/20/red-gate-to-continue-development-of-net-reflector.aspx</id><published>2008-08-20T07:04:54Z</published><updated>2008-08-20T07:04:54Z</updated><content type="html">&lt;p&gt;.NET Reflector, by Lutz Roeder, must be one of the most useful tools I have when developing .NET code. Usually it is the first thing I install right after Visual Studio not even waiting until I need it because I know I will.&lt;/p&gt; &lt;p&gt;So the big news is that Red Gate, makers of the Ants profiler and lots of other tools, are taking over from Lutz Roeder and will continue developing .NET Reflector. Interesting move and I hope this means a bright future for the .NET Reflector.&lt;/p&gt; &lt;p&gt;Read more about this &lt;a href="http://www.simple-talk.com/reflector/interview.htm"&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Enjoy!&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.theproblemsolver.nl/"&gt;www.TheProblemSolver.nl &lt;/a&gt;&lt;br /&gt;&lt;a href="http://wiki.windowsworkflowfoundation.eu/"&gt;Wiki.WindowsWorkflowFoundation.eu&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1645153" width="1" height="1"&gt;</content><author><name>Maurice</name><uri>http://msmvps.com/members/Maurice/default.aspx</uri></author><category term=".NET" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/.NET/default.aspx" /><category term="LINQ" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/LINQ/default.aspx" /><category term="NetFx3" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/NetFx3/default.aspx" /><category term="Workflow" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/Workflow/default.aspx" /><category term="VSTO" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/VSTO/default.aspx" /><category term="WCF" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/WCF/default.aspx" /><category term="VB" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/VB/default.aspx" /><category term="DevCenter" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/DevCenter/default.aspx" /><category term="WPF" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/WPF/default.aspx" /><category term="SqlCe" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/SqlCe/default.aspx" /></entry><entry><title>Two useful batch files when testing with Windows Workflow Foundation</title><link rel="alternate" type="text/html" href="/blogs/theproblemsolver/archive/2008/08/19/two-useful-batch-files-when-testing-with-windows-workflow-foundation.aspx" /><id>/blogs/theproblemsolver/archive/2008/08/19/two-useful-batch-files-when-testing-with-windows-workflow-foundation.aspx</id><published>2008-08-19T14:21:48Z</published><updated>2008-08-19T14:21:48Z</updated><content type="html">&lt;p&gt;&lt;/p&gt; &lt;p&gt;The following are two batch files I use a lot when working with WF persistence and or tracking as I find it desirable to clear the out often. Just drop them in the &amp;quot;C:\WINDOWS\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL\EN&amp;quot; directory with the four SQL scripts and recreating the required databases is just a few clicks away.&lt;/p&gt; &lt;h2&gt;CreatePersistence.bat&lt;/h2&gt; &lt;p&gt;osql -E -S .\sqlexpress -Q &amp;quot;Drop Database WorkflowPersistence&amp;quot;&lt;br /&gt;osql -E -S .\sqlexpress -Q &amp;quot;Create Database WorkflowPersistence&amp;quot; &lt;br /&gt;osql -E -S .\sqlexpress -d WorkflowPersistence -i SqlPersistenceService_Schema.sql&lt;br /&gt;osql -E -S .\sqlexpress -d WorkflowPersistence -i SqlPersistenceService_Logic.sql &lt;p&gt;&amp;nbsp; &lt;h2&gt;CreateTracking.bat&lt;/h2&gt; &lt;p&gt;osql -E -S .\sqlexpress -Q &amp;quot;Drop Database WorkflowTracking&amp;quot;&lt;br /&gt;osql -E -S .\sqlexpress -Q &amp;quot;Create Database WorkflowTracking&amp;quot; &lt;br /&gt;osql -E -S .\sqlexpress -d WorkflowTracking -i Tracking_Schema.sql&lt;br /&gt;osql -E -S .\sqlexpress -d WorkflowTracking -i Tracking_Logic.sql &lt;p&gt;&amp;nbsp; &lt;p&gt;Of course you could also use my SqlCeWFPersistence as the persistence service, download it from &lt;a href="http://code.msdn.microsoft.com/SqlCeWFPersistence"&gt;here&lt;/a&gt;. I never did create a TrackingService based upon SQL Compact but if enough people are interested I might just do so &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt; &lt;p&gt;Enjoy! &lt;p&gt;&lt;a href="http://www.theproblemsolver.nl/"&gt;www.TheProblemSolver.nl &lt;/a&gt;&lt;br /&gt;&lt;a href="http://wiki.windowsworkflowfoundation.eu/"&gt;Wiki.windowsworkflowfoundation.eu&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1645075" width="1" height="1"&gt;</content><author><name>Maurice</name><uri>http://msmvps.com/members/Maurice/default.aspx</uri></author></entry><entry><title>.NET Framework 3.5 Enhancements Training Kit</title><link rel="alternate" type="text/html" href="/blogs/theproblemsolver/archive/2008/08/19/net-framework-3-5-enhancements-training-kit.aspx" /><id>/blogs/theproblemsolver/archive/2008/08/19/net-framework-3-5-enhancements-training-kit.aspx</id><published>2008-08-19T10:32:52Z</published><updated>2008-08-19T10:32:52Z</updated><content type="html">&lt;p&gt;Want to know what is new in the .NET 3.5 SP1 framework or Visual Studio 2008 SP1? Then check out the presentations and labs here: &lt;a title="http://www.microsoft.com/downloads/details.aspx?FamilyID=355C80E9-FDE0-4812-98B5-8A03F5874E96&amp;amp;displaylang=en" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=355C80E9-FDE0-4812-98B5-8A03F5874E96&amp;amp;displaylang=en"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyID=355C80E9-FDE0-4812-98B5-8A03F5874E96&amp;amp;displaylang=en&lt;/a&gt;&lt;/p&gt; &lt;h2&gt;&amp;nbsp;&lt;/h2&gt; &lt;h2&gt;Overview&lt;/h2&gt; &lt;p&gt;The .NET Framework 3.5 Enhancements Training Kit includes presentations, hands-on labs, demos, and event materials. This content is designed to help you learn how to utilize the .NET 3.5 Enhancement features including: ASP.NET MVC, ASP.NET Dynamic Data, ASP.NET AJAX History, ASP.NET Routing, ADO.NET Data Services, ADO.NET Entity Framework, WCF 3.5 SP1, and the .NET Framework Client Profile.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Now this is nowhere near complete but a good place to start.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Enjoy!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1645044" width="1" height="1"&gt;</content><author><name>Maurice</name><uri>http://msmvps.com/members/Maurice/default.aspx</uri></author><category term=".NET" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/.NET/default.aspx" /><category term="LINQ" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/LINQ/default.aspx" /><category term="NetFx3" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/NetFx3/default.aspx" /><category term="DevCenter" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/DevCenter/default.aspx" /><category term="ClickOnce" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/ClickOnce/default.aspx" /><category term="SqlCe" scheme="http://msmvps.com/blogs/theproblemsolver/archive/tags/SqlCe/default.aspx" /></entry><entry><title>Calling IronPython functions from .NET</title><link rel="alternate" type="text/html" href="/blogs/theproblemsolver/archive/2008/08/14/calling-ironpython-functions-from-net.aspx" /><id>/blogs/theproblemsolver/archive/2008/08/14/calling-ironpython-functions-from-net.aspx</id><published>2008-08-14T18:17:19Z</published><updated>2008-08-14T18:17:19Z</updated><content type="html">&lt;p&gt;Having worked with Python in the past I find IronPython an interesting language to work with. However the story becomes really interesting if you can combine IronPython with regular strong typed code into one.&lt;/p&gt; &lt;p&gt;So I decided to take a look at what it would take to do so with the current IronPython version. I used IronPython 2 Beta 3, based upon the current version of the Dynamic Language Runtime, which is still evolving so the classes might have changed, take care! You can download the latest IronPython release &lt;a href="http://www.codeplex.com/IronPython"&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h3&gt;Lets take a look at what it takes to use an IronPython class from a Visual Basic Project.&lt;/h3&gt; &lt;p&gt; The first thing we need is a base class we are actually going to derive from. This is because IronPython doesn&amp;#39;t compile its code into a static type but VB requires its variables to be typed. This is the base class I am using:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Public Class &lt;/span&gt;HelloWorldVB
    &lt;span style="color:blue;"&gt;Public Overridable Function &lt;/span&gt;HelloWorld(&lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;name &lt;span style="color:blue;"&gt;As String&lt;/span&gt;) &lt;span style="color:blue;"&gt;As String
        Return String&lt;/span&gt;.Format(&lt;span style="color:#a31515;"&gt;&amp;quot;Hello &amp;#39;{0}&amp;#39; from Visual Basic&amp;quot;&lt;/span&gt;, name)
    &lt;span style="color:blue;"&gt;End Function
End Class
&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;And a main module to start thing off:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Sub &lt;/span&gt;Main()

    &lt;span style="color:blue;"&gt;Dim &lt;/span&gt;helloWorld &lt;span style="color:blue;"&gt;As New &lt;/span&gt;HelloWorldVB()
    Console.WriteLine(helloWorld.HelloWorld(&lt;span style="color:#a31515;"&gt;&amp;quot;Maurice&amp;quot;&lt;/span&gt;))

    Console.ReadLine()
&lt;span style="color:blue;"&gt;End Sub
&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;No big surprise here &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;So how do we derive an IronPython class from our VB type?&lt;/h3&gt;
&lt;p&gt;The following code is the IronPython code I added to the file HelloWorld.py.&lt;/p&gt;&lt;pre class="code"&gt;import clr
clr.AddReference(&amp;#39;IronPythonTest2&amp;#39;)
from IronPythonTest2 import HelloWorldVB

class HelloWorldIronPython(HelloWorldVB):
    def HelloWorld(self, name):
        return &amp;quot;Hello &amp;#39;&amp;quot; + name + &amp;quot;&amp;#39; from IronPython&amp;quot;
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Basically this code adds a reference to the IronPythonTest2 assembly, this is my console application containing the previous VB code. Next it imports the HelloWorldVB type from the assembly. Now it know about the type we can go ahead and derive from that type and create a new one. This exactly what the line class HelloWorldIronPython(HelloWorldVB) does, it creates a new type called HelloWorldIronPython. Next we override the HelloWorld function and return a different welcome string. A few things to note here: Python uses indentation to specify blocks, so the function being indented from the class is a part of that and the line of code with the return is indented from the def that defines the function so it is part of the function body. Another interesting thing is the self parameter. Every function in Python is passed a reference to itself as the first parameter. Sort of like the implicit Me in VB except a bit more obvious.&lt;/p&gt;
&lt;p&gt;If you want to know more about IronPython I suggest you get the book &lt;a href="http://www.manning.com/foord/"&gt;IronPython in Action&lt;/a&gt; from &lt;a href="http://www.voidspace.org.uk/python/weblog/index.shtml"&gt;Michael Foord&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.manning.com/foord/foord_cover150.jpg" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;To make sure the HelloWorld.py file is available to the console application I have set the&amp;nbsp; Copy to Output Directory to Copy always.&lt;/p&gt;
&lt;p&gt;OK so far so good. We have an IronPython class with the code we need. Now we still need to create an object from it. This isn&amp;#39;t hard it just takes a bit more doing than just using the New operator.&lt;/p&gt;
&lt;h3&gt;Instantiating the IronPython object&lt;/h3&gt;
&lt;p&gt;The first step is adding the required references. We need to add the following assemblies:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;IronPython.dll&lt;/li&gt;
&lt;li&gt;IronPython.Modules.dll&lt;/li&gt;
&lt;li&gt;Microsoft.Scripting.dll&lt;/li&gt;
&lt;li&gt;Microsoft.Scripting.Core.dll&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;We will only be using the 1st and 3rd ourselves but the others are needed as well.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Once we have the references set we can add the required Imports:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Imports &lt;/span&gt;Microsoft.Scripting.Hosting
&lt;span style="color:blue;"&gt;Imports &lt;/span&gt;IronPython.Hosting
&lt;span style="color:blue;"&gt;Imports &lt;/span&gt;IronPython.Runtime.Types
&lt;/pre&gt;
&lt;p&gt;And now we can get really going with the code &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;&lt;/p&gt;
&lt;p&gt;We need to load the file with the Python source code using an IronPython ScriptRuntime. Once done we can get a reference to the IronPython type object using the GetVariable() function by passing in the class name. Once we have that we call the ScriptRuntime again to actually create the object. See the code below:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Dim &lt;/span&gt;runtime &lt;span style="color:blue;"&gt;As &lt;/span&gt;ScriptRuntime = PythonEngine.CurrentEngine.Runtime
&lt;span style="color:blue;"&gt;Dim &lt;/span&gt;scope &lt;span style="color:blue;"&gt;As &lt;/span&gt;ScriptScope = runtime.ExecuteFile(&lt;span style="color:#a31515;"&gt;&amp;quot;HelloWorld.py&amp;quot;&lt;/span&gt;)
&lt;span style="color:blue;"&gt;Dim &lt;/span&gt;pythonType &lt;span style="color:blue;"&gt;As &lt;/span&gt;PythonType = scope.GetVariable(&lt;span style="color:blue;"&gt;Of &lt;/span&gt;PythonType)(&lt;span style="color:#a31515;"&gt;&amp;quot;HelloWorldIronPython&amp;quot;&lt;/span&gt;)
helloWorld = &lt;span style="color:blue;"&gt;CType&lt;/span&gt;(runtime.Operations.Call(pythonType), HelloWorldVB)
Console.WriteLine(helloWorld.HelloWorld(&lt;span style="color:#a31515;"&gt;&amp;quot;Maurice&amp;quot;&lt;/span&gt;))
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;And with this code we are good to go. Running the complete code will show the output below:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.CallingIronPythonfunctionsfrom.NET_5F00_113A8/image_5F00_2.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="146" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/theproblemsolver.CallingIronPythonfunctionsfrom.NET_5F00_113A8/image_5F00_thumb.png" width="335" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;The complete code in the main module:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Option Explicit On
Option Strict On

Imports &lt;/span&gt;Microsoft.Scripting.Hosting
&lt;span style="color:blue;"&gt;Imports &lt;/span&gt;IronPython.Hosting
&lt;span style="color:blue;"&gt;Imports &lt;/span&gt;IronPython.Runtime.Types

&lt;span style="color:blue;"&gt;Module &lt;/span&gt;Module1
    &lt;span style="color:blue;"&gt;Sub &lt;/span&gt;Main()
        &lt;span style="color:blue;"&gt;Dim &lt;/span&gt;helloWorld &lt;span style="color:blue;"&gt;As New &lt;/span&gt;HelloWorldVB()
        Console.WriteLine(helloWorld.HelloWorld(&lt;span style="color:#a31515;"&gt;&amp;quot;Maurice&amp;quot;&lt;/span&gt;))

        &lt;span style="color:blue;"&gt;Dim &lt;/span&gt;runtime &lt;span style="color:blue;"&gt;As &lt;/span&gt;ScriptRuntime = PythonEngine.CurrentEngine