<feed xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns="http://www.w3.org/2005/Atom" xml:lang="en-NZ">
    <title>PeteGoo</title>
    <link rel="self" type="application/atom+xml" href="http://blog.petegoo.com/blog/Atom.aspx" />
    <subtitle type="html">.Net Heebie Jeebies</subtitle>
    <id>http://blog.petegoo.com/blog/Default.aspx</id>
    <author>
        <name>PeteGoo</name>
        <uri>http://blog.petegoo.com/blog/Default.aspx</uri>
    </author>
    <generator uri="http://subtextproject.com" version="Subtext Version 2.2.0.0">Subtext</generator>
    <updated>2010-09-01T21:22:43Z</updated>
    <entry>
        <title>Code and slides for Dev208 at Tech Ed NZ</title>
        <link rel="alternate" type="text/html" href="http://blog.petegoo.com/blog/archive/2010/09/01/code-and-slides-for-dev208-at-tech-ed-nz.aspx" />
        <id>http://blog.petegoo.com/blog/archive/2010/09/01/code-and-slides-for-dev208-at-tech-ed-nz.aspx</id>
        <published>2010-09-01T09:48:39Z</published>
        <updated>2010-09-01T09:53:47Z</updated>
        <content type="html">&lt;p&gt;Here are the slides and demos for the Tech Ed NZ talk &lt;a title="Stefan Sewell's Blog" href="http://web.me.com/stefsewell/TechEd2010/" target="_blank"&gt;Stef&lt;/a&gt; and I did on Intro to Workflow 4. It includes the Approval Sample we didn’t manage to fit in.&lt;/p&gt;  &lt;p&gt;P.S. I know this blog sucks in IE, working on a fix when I get some time.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:F60BB8FA-6F02-4999-8F5E-9DD4E92C4DA7:350719bf-bc00-4346-8ce5-19d74e21ed47" class="wlWriterEditableSmartContent"&gt;&lt;div&gt;&lt;a href="http://blog.petegoo.com/blog/images/blog_petegoo_com/blog/WindowsLiveWriter/Codeandslidesfor_894F/DEV208-GettingStartedWithWorkflow.pptx" target="_self"&gt;DEV208-GettingStartedWithWorkflow.pptx&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;    &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:F60BB8FA-6F02-4999-8F5E-9DD4E92C4DA7:daf04593-bce8-46b0-b802-a36da8c3c0f5" class="wlWriterEditableSmartContent"&gt;&lt;div&gt;&lt;a href="http://blog.petegoo.com/blog/images/blog_petegoo_com/blog/WindowsLiveWriter/Codeandslidesfor_894F/Intro.To.WF.Demos.zip" target="_self"&gt;Intro To WF Demos.zip&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="/blog/aggbug/44.aspx" width="1" height="1" /&gt;</content>
    </entry>
    <entry>
        <title>Workflow 4: Human based workflows with an Email Approval Sample</title>
        <link rel="alternate" type="text/html" href="http://blog.petegoo.com/blog/archive/2010/08/22/workflow-4-email-approval-sample.aspx" />
        <id>http://blog.petegoo.com/blog/archive/2010/08/22/workflow-4-email-approval-sample.aspx</id>
        <published>2010-08-22T22:13:17Z</published>
        <updated>2010-09-01T21:22:43Z</updated>
        <content type="html">&lt;p&gt;One of the questions that a lot of people ask about workflow 4 is how to integrate manual tasks into the workflow process so that humans can be involved and interact with the workflow process. After all, what use is a stateful, long running service if no humans are involved? All of the activities that ship with workflow 4 and many of the samples provided only really cover programmatic activities but what about user interaction, I mean WF4 does not even ship with an email activity.&lt;/p&gt;  &lt;p&gt;The purpose of this post is to introduce the concept of a manual task into a workflow process and show how correlation can be used to help route service calls back to the originating workflow instance. &lt;/p&gt;  &lt;h2&gt;Scenario&lt;/h2&gt;  &lt;p&gt;The problem we will try to solve is that we have a textual statement that needs to be sent to a number of people (approvers) who must approve or decline, indicating their acceptance of the statement. Once all the approvers have completed their tasks a report of the number of approvals is sent to the requestor. We are going to use emails to send the manual tasks to our approvers. The emails will have “Approve” and “Decline” links in them, clicking these links will update the status of the task in the workflow.&lt;/p&gt;  &lt;h2&gt;The Workflow&lt;/h2&gt;  &lt;p&gt;We start our workflow by creating a Workflow Service Library project and adding the parameters to our Receive activity to take the list of approver emails, the message which will be the statement that should be accepted or declined and the email of the requestor so that the report can be sent back to them. These parameters will be assigned to variables within our workflow.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.petegoo.com/blog/images/blog_petegoo_com/blog/WindowsLiveWriter/98851c857a1e_11F48/ApprovalSampleInitialReceive_2.gif"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ApprovalSampleInitialReceive" border="0" alt="ApprovalSampleInitialReceive" src="http://blog.petegoo.com/blog/images/blog_petegoo_com/blog/WindowsLiveWriter/98851c857a1e_11F48/ApprovalSampleInitialReceive_thumb.gif" width="525" height="545" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Next we have to process each of the approval emails and handle the corresponding responses. The rest of the workflow is shown below.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.petegoo.com/blog/images/blog_petegoo_com/blog/WindowsLiveWriter/98851c857a1e_11F48/ApprovalWorkflow2_2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ApprovalWorkflow2" border="0" alt="ApprovalWorkflow2" src="http://blog.petegoo.com/blog/images/blog_petegoo_com/blog/WindowsLiveWriter/98851c857a1e_11F48/ApprovalWorkflow2_thumb.png" width="837" height="1134" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;So lets walk through it. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;ParallelForEach&amp;lt;string&amp;gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The first thing we need to consider is that we are going to process each of the approvals in parallel so that we are not dependent on the order of the responses. To do this we use a ParallelForEach&amp;lt;T&amp;gt; activity, this is essentially a parallel activity which will create a branch for each item in the source collection. The source collection in our case is the array of approver email addresses.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Send Approval and Wait for Response&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This sequence will contain all our processing for a single approver branch. The most important things here which can’t be seen from the above image are the variables that belong to this sequence.&lt;/p&gt;  &lt;p&gt;- approverId :This is a unique Guid initialised here to a new random guid. This will be used as a unique identifier for this approver.&lt;/p&gt;  &lt;p&gt;- ApprovalCorrelationHandle: A correlation handle is a special type in workflow which holds information about how an incoming information can find our instance More on this later.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Send Approver Email&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;First we construct and send an email using a custom SendEmail activity included in the source. The implementation of this activity is not important, for our purposes all we care about is that it has four arguments, ToAddress, FromAddress, Subject and Body. The body contains an HTML message with Accept an Decline links to the web site we will create later.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: #a31515"&gt;"&amp;lt;html&amp;gt;" &lt;/span&gt;&amp;amp; _
&lt;span style="color: #a31515"&gt;"  &amp;lt;body&amp;gt;" &lt;/span&gt;&amp;amp; _
&lt;span style="color: #a31515"&gt;"    &amp;lt;p&amp;gt;Please approve or decline the following statement:&amp;lt;/p&amp;gt;" &lt;/span&gt;&amp;amp; _
&lt;span style="color: #a31515"&gt;"    &amp;lt;h2&amp;gt;" &lt;/span&gt;&amp;amp; messageToApprove &amp;amp; &lt;span style="color: #a31515"&gt;"&amp;lt;/h2&amp;gt;" &lt;/span&gt;&amp;amp; _
&lt;span style="color: #a31515"&gt;"    &amp;lt;a href=""http://localhost/TechEdNZ/Approval.Web/Approval/Approve/" &lt;/span&gt;&amp;amp; approverId.ToString() &amp;amp; &lt;span style="color: #a31515"&gt;"""&amp;gt;Approve&amp;lt;/a&amp;gt;&amp;lt;br/&amp;gt;" &lt;/span&gt;&amp;amp; _
&lt;span style="color: #a31515"&gt;"    &amp;lt;a href=""http://localhost/TechEdNZ/Approval.Web/Approval/Decline/" &lt;/span&gt;&amp;amp; approverId.ToString() &amp;amp; &lt;span style="color: #a31515"&gt;"""&amp;gt;Decline&amp;lt;/a&amp;gt;&amp;lt;br/&amp;gt;" &lt;/span&gt;&amp;amp; _
&lt;span style="color: #a31515"&gt;"  &amp;lt;/body&amp;gt;" &lt;/span&gt;&amp;amp; _
&lt;span style="color: #a31515"&gt;"&amp;lt;/html&amp;gt;"
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;As you can see it contains a bunch of not so pretty VB string concatenation. Not ideal but fit for our purposes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;InitializeCorrelation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The initialize correlation activity is used to setup our CorrelationHandle we declared earlier, We simply set the name of a correlation key “approverId” to the value of our guid variable “approverId.ToString()”. This means that we now have a correlation handle which can be used later on our Receive activity to allow the runtime to find this specific instance when the Receive endpoint is called with a compatible correlation parameter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pick&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A pick is a very useful activity which basically says, perform each of my branches’ “trigger” sections in parallel and when the first one of them completes, cancel the other branched and run the completed branches’ “action” section. This is especially useful if you want to setup a number of Receive activities, essentially presenting a choice, and continue the workflow when a choice is made. In our case these triggers will be our Accept and Decline Receive activities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Receive and SendReply&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The two receive activities are simply operations on the same endpoint named “Accept” and “Decline”, they both have a single parameter called approverId which correlates to our unique guid via our CorrelationHandle, for more on how to setup correlation, see my &lt;a href="http://blog.petegoo.com/archive/2010/06/27/wf4-services-part-2-ndash-correlation.aspx" target="_blank"&gt;previous post on the subject&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Assign&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The assign simply increments an approval counter if the approver selected Approve&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Send Result Email&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The send result sends the approval count to the original requestor.&lt;/p&gt;

&lt;h2&gt;The Web App&lt;/h2&gt;

&lt;p&gt;Unfortunately, WF4 does not easily support REST as a communication mechanism for its Receive activities so we needed the links in our email to present a confirmation to the approver and at the same time call our workflow. This was most easily accomplished via an ASP.Net MVC2 web application with an ApprovalController as follows:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ApprovalController &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;Controller &lt;/span&gt;{

    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ActionResult &lt;/span&gt;Approve(&lt;span style="color: blue"&gt;string &lt;/span&gt;id) {
        ApprovalWorkflowService.&lt;span style="color: #2b91af"&gt;ServiceClient &lt;/span&gt;serviceClient = &lt;span style="color: blue"&gt;new &lt;/span&gt;ApprovalWorkflowService.&lt;span style="color: #2b91af"&gt;ServiceClient&lt;/span&gt;();
        serviceClient.Approve(id);
        &lt;span style="color: blue"&gt;return &lt;/span&gt;View();
    }

    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ActionResult &lt;/span&gt;Decline(&lt;span style="color: blue"&gt;string &lt;/span&gt;id) {
        ApprovalWorkflowService.&lt;span style="color: #2b91af"&gt;ServiceClient &lt;/span&gt;serviceClient = &lt;span style="color: blue"&gt;new &lt;/span&gt;ApprovalWorkflowService.&lt;span style="color: #2b91af"&gt;ServiceClient&lt;/span&gt;();
        serviceClient.Decline(id);
        &lt;span style="color: blue"&gt;return &lt;/span&gt;View();
    }

}&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;font face="Lucida Sans Unicode"&gt;The RouteMapping in ASP.Net MVC will automatically turn our email link into the above method call which in turn will call our workflow with the appropriate approverId.&lt;/font&gt;&lt;/pre&gt;

&lt;h2&gt;The Client&lt;/h2&gt;

&lt;p&gt;The client app here is just a console app with the following code:&lt;/p&gt;

&lt;pre class="code"&gt;ApprovalWorkflowService.&lt;span style="color: #2b91af"&gt;ServiceClient &lt;/span&gt;client = &lt;span style="color: blue"&gt;new &lt;/span&gt;ApprovalWorkflowService.&lt;span style="color: #2b91af"&gt;ServiceClient&lt;/span&gt;();
client.BeginApprovalProcess(&lt;span style="color: blue"&gt;new&lt;/span&gt;[] {
                                      &lt;span style="color: #a31515"&gt;"approver1@foo.com"&lt;/span&gt;, 
                                      &lt;span style="color: #a31515"&gt;"approver2@foo.com"&lt;/span&gt;, 
                                      &lt;span style="color: #a31515"&gt;"approver3@foo.com"
                                  &lt;/span&gt;}, 
                                  &lt;span style="color: #a31515"&gt;"Holiday approval for Joe Bloggs from 2nd December to 12th January?"&lt;/span&gt;, 
                                  &lt;span style="color: #a31515"&gt;"joe.bloggs@foo.com"&lt;/span&gt;);&lt;/pre&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;And that’s about it. Correlation comes to the rescue enabling us to send the 3 emails to the above addresses and, when they all click the links in their emails, the MVC app sends a message to our workflow definition. That message is routed to the correct workflow instance because the Receive activity told the runtime to wait for a call to “Accept” with one of 3 approver ids and to route that call to our instance. After they have all responded the workflow will continue past the ParallelForEach and the result is sent.&lt;/p&gt;

&lt;p&gt;This application is fully compliant with pretty much any platform that has email and a browser and that’s as as simple as it gets.&lt;/p&gt;

&lt;h2&gt;What Next&lt;/h2&gt;

&lt;p&gt;This is just the beginning of how manual tasks can work in workflow. You could start to expand on this concept by mapping more data into your emails so that the approver is doing something more useful. Another option is to implement a threshold using a simple “If” so that e.g. 2 out of 3 approvers must approve and the workflow could subsequently decide whether to make a call to an HR service or something similar.&lt;/p&gt;

&lt;p&gt;I hope you found this post helpful, code below.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:F60BB8FA-6F02-4999-8F5E-9DD4E92C4DA7:8ab5b3e8-a679-434b-8e69-28e274031ef4" class="wlWriterEditableSmartContent"&gt;&lt;div&gt;&lt;a href="http://blog.petegoo.com/blog/images/blog_petegoo_com/blog/WindowsLiveWriter/98851c857a1e_11F48/PeteGooApprovalSample.zip" target="_self"&gt;PeteGooApprovalSample.zip&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="/blog/aggbug/43.aspx" width="1" height="1" /&gt;</content>
    </entry>
    <entry>
        <title>Unit Test Workflow 4 Activities : Dependency Injection</title>
        <link rel="alternate" type="text/html" href="http://blog.petegoo.com/blog/archive/2010/08/16/unit-test-workflow-4-activities-dependency-injection.aspx" />
        <id>http://blog.petegoo.com/blog/archive/2010/08/16/unit-test-workflow-4-activities-dependency-injection.aspx</id>
        <published>2010-08-16T15:04:53Z</published>
        <updated>2010-08-16T15:04:53Z</updated>
        <content type="html">&lt;p&gt;At first glance unit testing workflow activities with &lt;a title="Martin Fowler on Dependency Injection" href="http://martinfowler.com/articles/injection.html" target="_blank"&gt;dependency injection&lt;/a&gt; seems like a no-brainer. For example consider the following activity using constructor-based dependency injection.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SendEmail &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;CodeActivity &lt;/span&gt;{
    &lt;span style="color: blue"&gt;private readonly &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEmailClient &lt;/span&gt;emailClient;

    &lt;span style="color: blue"&gt;public &lt;/span&gt;SendEmail() : &lt;span style="color: blue"&gt;this&lt;/span&gt;(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EmailClient&lt;/span&gt;()) {}

    &lt;span style="color: blue"&gt;public &lt;/span&gt;SendEmail(&lt;span style="color: #2b91af"&gt;IEmailClient &lt;/span&gt;emailClient) {
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.emailClient = emailClient;
    }

    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;InArgument&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; To { &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;&lt;span style="color: #2b91af"&gt;InArgument&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; From { &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;&lt;span style="color: #2b91af"&gt;InArgument&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; Subject { &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;&lt;span style="color: #2b91af"&gt;InArgument&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;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 void &lt;/span&gt;Execute(&lt;span style="color: #2b91af"&gt;CodeActivityContext &lt;/span&gt;context) {
        emailClient.SendEmail(
            To.Get(context),
            From.Get(context),
            Subject.Get(context),
            Message.Get(context)
            );
    }
}

&lt;span style="color: blue"&gt;public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEmailClient &lt;/span&gt;{
    &lt;span style="color: blue"&gt;void &lt;/span&gt;SendEmail(&lt;span style="color: blue"&gt;string &lt;/span&gt;to, &lt;span style="color: blue"&gt;string &lt;/span&gt;from, &lt;span style="color: blue"&gt;string &lt;/span&gt;subject, &lt;span style="color: blue"&gt;string &lt;/span&gt;message);
}

&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EmailClient &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;IEmailClient &lt;/span&gt;{
    &lt;span style="color: blue"&gt;public void &lt;/span&gt;SendEmail(&lt;span style="color: blue"&gt;string &lt;/span&gt;to, &lt;span style="color: blue"&gt;string &lt;/span&gt;from, &lt;span style="color: blue"&gt;string &lt;/span&gt;subject, &lt;span style="color: blue"&gt;string &lt;/span&gt;message) {
        &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #00008b"&gt;NotImplementedException&lt;/span&gt;();
    }
}
&lt;/font&gt;&lt;/pre&gt;


&lt;p&gt; &lt;/p&gt;

&lt;p&gt;I have an email client but I choose to write my tests so that I can replace the implementation of IEmailClient such that I can stub or mock the implementation out as below. This is absolutely necessary for unit testing as we cannot have our real implementation of the Email Client sending emails when we run our unit tests. Therefore we swap out with a stub implementation that simply logs the fact that we have called SendEmail.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;font size="2"&gt;[&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]
&lt;span style="color: blue"&gt;public void &lt;/span&gt;ExecuteCallsSendEmailOnClient() {
    &lt;span style="color: #2b91af"&gt;StubEmailClient &lt;/span&gt;stubEmailClient = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;StubEmailClient&lt;/span&gt;();
    &lt;span style="color: #2b91af"&gt;WorkflowInvoker&lt;/span&gt;.Invoke(
        &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SendEmail&lt;/span&gt;(
            stubEmailClient) {
                                       From = &lt;span style="color: #a31515"&gt;"foo@foo.com"&lt;/span&gt;,
                                       To = &lt;span style="color: #a31515"&gt;"bar@bar.com"&lt;/span&gt;,
                                       Subject = &lt;span style="color: #a31515"&gt;"The Subject"&lt;/span&gt;,
                                       Message = &lt;/font&gt;&lt;font size="2"&gt;&lt;span style="color: #a31515"&gt;"The Message"
                                   &lt;/span&gt;});

    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(1, stubEmailClient.SentEmails);
}

&lt;span style="color: blue"&gt;private class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;StubEmailClient &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;IEmailClient &lt;/span&gt;{
    &lt;span style="color: blue"&gt;private int &lt;/span&gt;sentEmails;
    &lt;span style="color: blue"&gt;public int &lt;/span&gt;SentEmails {
        &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return &lt;/span&gt;sentEmails; }
    }
    &lt;span style="color: blue"&gt;public void &lt;/span&gt;SendEmail(&lt;span style="color: blue"&gt;string &lt;/span&gt;to, &lt;span style="color: blue"&gt;string &lt;/span&gt;from, &lt;span style="color: blue"&gt;string &lt;/span&gt;subject, &lt;span style="color: blue"&gt;string &lt;/span&gt;message) {
        sentEmails++;
    }
}&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;So great! Now we have unit tested our activity and all is good with the world, no different from any other unit testing, right? But what if I have a workflow activity written in XAML that uses my SendEmail activity. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Activity &lt;/span&gt;&lt;span style="color: red"&gt;mc:Ignorable&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;sap&lt;/span&gt;"
          &lt;span style="color: red"&gt;x:Class&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;PeteGoo.TimeService.Activities.SendMultipleEmails&lt;/span&gt;"
          &lt;span style="color: red"&gt;xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;http://schemas.microsoft.com/netfx/2009/xaml/activities&lt;/span&gt;"
          &lt;span style="color: red"&gt;xmlns:local&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;clr-namespace:PeteGoo.TimeService.Activities&lt;/span&gt;"
          &lt;span style="color: red"&gt;xmlns:mc&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;http://schemas.openxmlformats.org/markup-compatibility/2006&lt;/span&gt;" 
          &lt;span style="color: red"&gt;xmlns:mva&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities&lt;/span&gt;" 
          &lt;span style="color: red"&gt;xmlns:sad&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;clr-namespace:System.Activities.Debugger;assembly=System.Activities&lt;/span&gt;"
          &lt;span style="color: red"&gt;xmlns:sap&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation&lt;/span&gt;" 
          &lt;span style="color: red"&gt;xmlns:x&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;http://schemas.microsoft.com/winfx/2006/xaml&lt;/span&gt;"&lt;/font&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;x:&lt;/span&gt;&lt;span style="color: red"&gt;Members&lt;/span&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;x:&lt;/span&gt;&lt;span style="color: red"&gt;Property Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;FromAddress&lt;/span&gt;"
                &lt;span style="color: red"&gt;Type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;InArgument(x:String)&lt;/span&gt;" &lt;/font&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;x:&lt;/span&gt;&lt;span style="color: red"&gt;Property Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;Subject&lt;/span&gt;"
                &lt;span style="color: red"&gt;Type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;InArgument(x:String)&lt;/span&gt;" &lt;/font&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;x:&lt;/span&gt;&lt;span style="color: red"&gt;Property Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;Message&lt;/span&gt;"
                &lt;span style="color: red"&gt;Type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;InArgument(x:String)&lt;/span&gt;" &lt;/font&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;x:&lt;/span&gt;&lt;span style="color: red"&gt;Property Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;ToAddresses&lt;/span&gt;"
                &lt;span style="color: red"&gt;Type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;InArgument(s:String[])&lt;/span&gt;" &lt;/font&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;/&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;x:&lt;/span&gt;&lt;span style="color: red"&gt;Members&lt;/span&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ForEach &lt;/span&gt;&lt;span style="color: red"&gt;x:TypeArguments&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;x:String&lt;/span&gt;"
           &lt;span style="color: red"&gt;DisplayName&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;ForEach&lt;/span&gt;&lt;span style="color: red"&gt;&amp;amp;lt;&lt;/span&gt;&lt;span style="color: blue"&gt;String&lt;/span&gt;&lt;span style="color: red"&gt;&amp;amp;gt;&lt;/span&gt;"
           &lt;span style="color: red"&gt;sad:XamlDebuggerXmlReader.FileName&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;E:\Code\Blog\UnitTestingActivities\PeteGoo.TimeService.Activities\SendMultipleEmails.xaml&lt;/span&gt;"
           &lt;span style="color: red"&gt;sap:VirtualizedContainerService.HintSize&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;287,206&lt;/span&gt;"
           &lt;span style="color: red"&gt;Values&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;[ToAddresses]&lt;/span&gt;"&lt;/font&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ActivityAction &lt;/span&gt;&lt;span style="color: red"&gt;x:TypeArguments&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;x:String&lt;/span&gt;"&lt;/font&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ActivityAction.&lt;/span&gt;&lt;span style="color: red"&gt;Argument&lt;/span&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;DelegateInArgument &lt;/span&gt;&lt;span style="color: red"&gt;x:TypeArguments&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;x:String&lt;/span&gt;"
                            &lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;toAddress&lt;/span&gt;" &lt;/font&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;/&amp;gt;
      &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ActivityAction.&lt;/span&gt;&lt;span style="color: red"&gt;Argument&lt;/span&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;local:SendEmail &lt;/span&gt;&lt;span style="color: red"&gt;From&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;[FromAddress]&lt;/span&gt;"
                       &lt;span style="color: red"&gt;sap:VirtualizedContainerService.HintSize&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;257,100&lt;/span&gt;"
                       &lt;span style="color: red"&gt;Message&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;[Message]&lt;/span&gt;"
                       &lt;span style="color: red"&gt;Subject&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;[Subject]&lt;/span&gt;"
                       &lt;span style="color: red"&gt;To&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;[toAddress]&lt;/span&gt;" &lt;/font&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ActivityAction&lt;/span&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ForEach&lt;/span&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Activity&lt;/span&gt;&lt;/font&gt;&lt;span style="color: blue"&gt;&lt;font size="2"&gt;&amp;gt;
&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;



&lt;p&gt;Now suppose I want to test my XAML activity, how can I use dependency injection? XAML is now in control of the construction, so I cannot use constructor based Dependency Injection. This is a big problem as we really want to use the composition model that WF4 provides us and the declarative programming model of XAML but that stops us from using familiar unit testing techniques. Yes, there are other types of dependency injection but maybe workflow extensions can be useful here.Workflow Extensions allow us to provide common services in a Service Locator pattern built into the execution context. Typically they are used for Tracking Participants and Persistence Participants which are recognised as they implement a well known contract, in this case however we are going to take advantage of the fact that workflow extensions can be any arbitrary type. Consider the following workflow extension and the associated Extension method.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DependencyInjectionExtension &lt;/span&gt;{

    &lt;span style="color: blue"&gt;private readonly &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt; dependencies = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;();
    &lt;span style="color: blue"&gt;public void &lt;/span&gt;AddDependency&amp;lt;T&amp;gt;(T instance) {
        dependencies.Add(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(T), instance);
    }

    &lt;span style="color: blue"&gt;public &lt;/span&gt;T GetDependency&amp;lt;T&amp;gt;(&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T&amp;gt; defaultFunc) &lt;span style="color: blue"&gt;where &lt;/span&gt;T : &lt;span style="color: blue"&gt;class &lt;/span&gt;{
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(dependencies.ContainsKey(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(T))) {
            &lt;span style="color: blue"&gt;return &lt;/span&gt;dependencies[&lt;span style="color: blue"&gt;typeof &lt;/span&gt;(T)] &lt;span style="color: blue"&gt;as &lt;/span&gt;T;
        }

        &lt;span style="color: blue"&gt;return &lt;/span&gt;defaultFunc();
    }
}

&lt;span style="color: blue"&gt;public static class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ActivityContextExtensions &lt;/span&gt;{
    &lt;span style="color: blue"&gt;public static &lt;/span&gt;T GetDependency&amp;lt;T&amp;gt;(&lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ActivityContext &lt;/span&gt;context, &lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T&amp;gt; defaultFunc) &lt;span style="color: blue"&gt;where &lt;/span&gt;T : &lt;span style="color: blue"&gt;class &lt;/span&gt;{
        &lt;span style="color: #2b91af"&gt;DependencyInjectionExtension &lt;/span&gt;extension = context.GetExtension&amp;lt;&lt;span style="color: #2b91af"&gt;DependencyInjectionExtension&lt;/span&gt;&amp;gt;();
        
        &lt;span style="color: blue"&gt;return &lt;/span&gt;extension == &lt;span style="color: blue"&gt;null &lt;/span&gt;? defaultFunc() : extension.GetDependency&amp;lt;T&amp;gt;(defaultFunc);
        
    }
}&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Now we can use this extension and the extension method to change our Execute implementation to the following.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;protected override void &lt;/span&gt;Execute(&lt;span style="color: #2b91af"&gt;CodeActivityContext &lt;/span&gt;context) {
    &lt;span style="color: #2b91af"&gt;IEmailClient &lt;/span&gt;client = context.GetDependency&amp;lt;&lt;span style="color: #2b91af"&gt;IEmailClient&lt;/span&gt;&amp;gt;(() =&amp;gt; &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EmailClient&lt;/span&gt;());

    client.SendEmail(
        To.Get(context),
        From.Get(context),
        Subject.Get(context),
        Message.Get(context)
        );
}&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;This shows that we will ask the GetDependency extension method for a certain service (IEmailClient) and if it has not been specified simply use a new EmailClient instance. The extension method in turn, checks whether the extension has been added and if so asks it for the dependency. If the extension is not present or it does not contain a dependency for our type then the supplied func is called which will return that EmailClient instance. And our test is as follows:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;font size="2"&gt;[&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]
&lt;span style="color: blue"&gt;public void &lt;/span&gt;ExecuteCallsSendEmailOnClient() {
    &lt;span style="color: #2b91af"&gt;StubEmailClient &lt;/span&gt;stubEmailClient = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;StubEmailClient&lt;/span&gt;();

    &lt;span style="color: #2b91af"&gt;WorkflowInvoker &lt;/span&gt;invoker = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;WorkflowInvoker&lt;/span&gt;(
        &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SendEmail &lt;/span&gt;{
                                       From = &lt;span style="color: #a31515"&gt;"foo@foo.com"&lt;/span&gt;,
                                       To = &lt;span style="color: #a31515"&gt;"bar@bar.com"&lt;/span&gt;,
                                       Subject = &lt;span style="color: #a31515"&gt;"The Subject"&lt;/span&gt;,
                                       Message = &lt;/font&gt;&lt;font size="2"&gt;&lt;span style="color: #a31515"&gt;"The Message"
                                   
        &lt;/span&gt;});

    &lt;span style="color: #2b91af"&gt;DependencyInjectionExtension &lt;/span&gt;dependencyInjectionExtension = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DependencyInjectionExtension&lt;/span&gt;();
    dependencyInjectionExtension.AddDependency&amp;lt;&lt;span style="color: #2b91af"&gt;IEmailClient&lt;/span&gt;&amp;gt;(stubEmailClient);

    invoker.Extensions.Add(dependencyInjectionExtension);

    invoker.Invoke();

    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(1, stubEmailClient.SentEmails);
}&lt;/font&gt;&lt;/pre&gt;


&lt;p&gt; &lt;/p&gt;

&lt;p&gt;So now we have implemented a dependency injection pattern explicitly for workflow activities. We can now test composite XAML or code-based activities as well as ordinary code activities without requiring that we stay in control of the construction of our object instances.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:F60BB8FA-6F02-4999-8F5E-9DD4E92C4DA7:f0b4dfdc-efb7-45e7-b0fe-73569988a506" class="wlWriterEditableSmartContent"&gt;&lt;div&gt;&lt;a href="http://blog.petegoo.com/images/blog_petegoo_com/WindowsLiveWriter/f8b5425ec662_135EE/UnitTestingActivities.zip" target="_self"&gt;UnitTestingActivities.zip&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="/blog/aggbug/42.aspx" width="1" height="1" /&gt;</content>
    </entry>
    <entry>
        <title>Unit Testing Workflow 4 Activities : The TestContext Tracking Participant</title>
        <link rel="alternate" type="text/html" href="http://blog.petegoo.com/blog/archive/2010/08/16/unit-testing-workflow-4-activities-the-testcontext-tracking-participant.aspx" />
        <id>http://blog.petegoo.com/blog/archive/2010/08/16/unit-testing-workflow-4-activities-the-testcontext-tracking-participant.aspx</id>
        <published>2010-08-16T13:48:52Z</published>
        <updated>2010-08-16T13:48:52Z</updated>
        <content type="html">&lt;p&gt;I’m a big believer in using &lt;a title="TestContext on MSDN" href="http://msdn.microsoft.com/en-us/library/ms404699(VS.80).aspx" target="_blank"&gt;TestContext&lt;/a&gt; in MSTest or Console.WriteLine, Debug.WriteLine etc in your favourite Unit Testing framework to give context to passed or failed tests. Especially if you do &lt;a title="Continuous Integration on Wikipedia" href="http://en.wikipedia.org/wiki/Continuous_integration" target="_blank"&gt;CI&lt;/a&gt; and have only the test results to look at from the build server to try to understand why a build went wrong.&lt;/p&gt;  &lt;p&gt;Taking this into account I use a TestContext Tracking Participant to get more visibility into my workflow unit tests. This enables me to see what tracking records have been raised against my invoked workflows. In only a few lines of code you can quickly enable extra logging.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TestContextTrackingParticipant &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;TrackingParticipant &lt;/span&gt;{
    &lt;span style="color: blue"&gt;private readonly &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TestContext &lt;/span&gt;testContext;

    &lt;span style="color: blue"&gt;public &lt;/span&gt;TestContextTrackingParticipant(&lt;span style="color: #2b91af"&gt;TestContext &lt;/span&gt;testContext) {
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.testContext = testContext;
    }

    &lt;span style="color: blue"&gt;protected override void &lt;/span&gt;Track(&lt;span style="color: #2b91af"&gt;TrackingRecord &lt;/span&gt;record, &lt;span style="color: #2b91af"&gt;TimeSpan &lt;/span&gt;timeout) {
        testContext.WriteLine(&lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;"- {0}"&lt;/span&gt;, 
            record.ToString()
            .Replace(&lt;span style="color: #a31515"&gt;"{"&lt;/span&gt;, &lt;span style="color: #a31515"&gt;"{{"&lt;/span&gt;)
            .Replace(&lt;span style="color: #a31515"&gt;"}"&lt;/span&gt;, &lt;span style="color: #a31515"&gt;"}}"&lt;/span&gt;)));
    }
}
&lt;/font&gt;&lt;/pre&gt;


&lt;p&gt; &lt;/p&gt;

&lt;p&gt;The only issue is that our invoker code from the &lt;a title="Unit Testing Basics" href="http://blog.petegoo.com/archive/2010/08/16/unit-testing-workflow-4-activities-basics.aspx" target="_blank"&gt;previous post&lt;/a&gt; is a little more verbose.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;font size="2"&gt;[&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]
&lt;span style="color: blue"&gt;public void &lt;/span&gt;ExecuteConvertsTimeToTargetCity() {

    &lt;span style="color: #2b91af"&gt;DateTime &lt;/span&gt;currentLocalTime = &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now;
    &lt;span style="color: blue"&gt;string &lt;/span&gt;cityName = &lt;span style="color: #a31515"&gt;"London"&lt;/span&gt;;

    &lt;span style="color: #2b91af"&gt;TimeZoneInfo &lt;/span&gt;timeZoneInfo =
        &lt;span style="color: #2b91af"&gt;TimeZoneInfo&lt;/span&gt;.GetSystemTimeZones().Where(
            timeZone =&amp;gt; timeZone.DisplayName.ToUpperInvariant().Contains(cityName.ToUpperInvariant())).First();

    &lt;span style="color: #2b91af"&gt;GetCityTime &lt;/span&gt;activity = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;GetCityTime&lt;/span&gt;() {
                                                    City = cityName,
                                                    LocalTime = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;InArgument&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;&amp;gt;(currentLocalTime)
                                                };
    &lt;span style="color: #2b91af"&gt;WorkflowInvoker &lt;/span&gt;invoker = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;WorkflowInvoker&lt;/span&gt;(activity);

    invoker.Extensions.Add(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TestContextTrackingParticipant&lt;/span&gt;(TestContext));

    &lt;span style="color: #2b91af"&gt;DateTime &lt;/span&gt;result = (&lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;)invoker.Invoke()[&lt;span style="color: #a31515"&gt;"Result"&lt;/span&gt;];

    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: #2b91af"&gt;TimeZoneInfo&lt;/span&gt;.ConvertTime(currentLocalTime, timeZoneInfo), result);
}&lt;/font&gt;&lt;/pre&gt;&lt;img src="/blog/aggbug/41.aspx" width="1" height="1" /&gt;</content>
    </entry>
    <entry>
        <title>Unit Testing Workflow 4 Activities : Basics</title>
        <link rel="alternate" type="text/html" href="http://blog.petegoo.com/blog/archive/2010/08/16/unit-testing-workflow-4-activities-basics.aspx" />
        <id>http://blog.petegoo.com/blog/archive/2010/08/16/unit-testing-workflow-4-activities-basics.aspx</id>
        <published>2010-08-16T13:22:42Z</published>
        <updated>2010-08-16T13:22:42Z</updated>
        <content type="html">&lt;p&gt;Unit testing workflows became a lot easier in WF4. The basic approach is the same as for normal code classes except for a few differences which we will cover in the posts in this series.&lt;/p&gt;  &lt;p&gt;Lets start off with a simple code activity which will return the time in a given city.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;GetCityTime &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;CodeActivity&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;&amp;gt;{

    [&lt;span style="color: #2b91af"&gt;RequiredArgument&lt;/span&gt;]
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;InArgument&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; City { &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;&lt;span style="color: #2b91af"&gt;InArgument&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;&amp;gt; LocalTime { &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;DateTime &lt;/span&gt;Execute(&lt;span style="color: #2b91af"&gt;CodeActivityContext &lt;/span&gt;context) {
        &lt;span style="color: blue"&gt;string &lt;/span&gt;city = City.Get(context);

        &lt;span style="color: #2b91af"&gt;TimeZoneInfo &lt;/span&gt;timeZoneInfo = GetTimeZoneForCity(city);
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(timeZoneInfo == &lt;span style="color: blue"&gt;null&lt;/span&gt;) {
            &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ArgumentOutOfRangeException&lt;/span&gt;(&lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;"Could not find timezone matching city '{0}'"&lt;/span&gt;, city));
        }

        &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TimeZoneInfo&lt;/span&gt;.ConvertTime(LocalTime == &lt;span style="color: blue"&gt;null &lt;/span&gt;? &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now : LocalTime.Get(context), timeZoneInfo);
    }

    &lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TimeZoneInfo &lt;/span&gt;GetTimeZoneForCity(&lt;span style="color: blue"&gt;string &lt;/span&gt;city) {
        &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TimeZoneInfo&lt;/span&gt;.GetSystemTimeZones()
            .Where(
                timezone =&amp;gt; timezone.DisplayName.ToUpperInvariant().Contains(city.ToUpperInvariant()))
            .FirstOrDefault();

    }
}&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;So lets start to build our first test. The &lt;a title="WorkflowInvoker on MSDN" href="http://msdn.microsoft.com/en-us/library/system.activities.workflowinvoker.aspx" target="_blank"&gt;WorkflowInvoker&lt;/a&gt; class allows us to execute a workflow activity in a blocking manner, meaning that it will execute the activity and wait for completion before continuing. We begin by testing that the City argument in indeed a required argument. This is always a good place to start and will make you think about the validations in your activity.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;font size="2"&gt;[&lt;span style="color: #2b91af"&gt;ExpectedException&lt;/span&gt;(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ArgumentException&lt;/span&gt;))]
[&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]
&lt;span style="color: blue"&gt;public void &lt;/span&gt;CityIsARequiredArgument() {
    &lt;span style="color: #2b91af"&gt;WorkflowInvoker&lt;/span&gt;.Invoke(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;GetCityTime&lt;/span&gt;());
}
&lt;/font&gt;&lt;/pre&gt;


&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Next we are going to check that providing an invalid value for City will indeed throw an exception.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;font size="2"&gt;[&lt;span style="color: #2b91af"&gt;ExpectedException&lt;/span&gt;(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ArgumentOutOfRangeException&lt;/span&gt;))]
[&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]
&lt;span style="color: blue"&gt;public void &lt;/span&gt;InvalidCityThrowsArgumentException() {
    &lt;span style="color: #2b91af"&gt;WorkflowInvoker&lt;/span&gt;.Invoke(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;GetCityTime&lt;/span&gt;() {City = &lt;span style="color: #a31515"&gt;"BlaBlaBla"&lt;/span&gt;});
}
&lt;/font&gt;&lt;/pre&gt;



&lt;p&gt;The last test is to check the actual execution. A handy feature of the WorkflowInvoker generic static methods are that you can execute an Activity&amp;lt;T&amp;gt; and the return signature of the WorkflowInvoker.Invoke method will be the Result type of our Activity (T).&lt;/p&gt;

&lt;pre class="code"&gt;&lt;font size="2"&gt;[&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]
&lt;span style="color: blue"&gt;public void &lt;/span&gt;ExecuteConvertsTimeToTargetCity() {
    &lt;span style="color: #2b91af"&gt;DateTime &lt;/span&gt;currentLocalTime = &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now;
    &lt;span style="color: blue"&gt;string &lt;/span&gt;cityName = &lt;span style="color: #a31515"&gt;"London"&lt;/span&gt;;

    &lt;span style="color: #2b91af"&gt;TimeZoneInfo &lt;/span&gt;timeZoneInfo =
        &lt;span style="color: #2b91af"&gt;TimeZoneInfo&lt;/span&gt;.GetSystemTimeZones().Where(
            timeZone =&amp;gt; timeZone.DisplayName.ToUpperInvariant().Contains(cityName.ToUpperInvariant())).First();

    &lt;span style="color: #2b91af"&gt;DateTime &lt;/span&gt;result = &lt;span style="color: #2b91af"&gt;WorkflowInvoker&lt;/span&gt;.Invoke(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;GetCityTime&lt;/span&gt;() {
                                                          City = cityName,
                                                          LocalTime = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;InArgument&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;&amp;gt;(currentLocalTime)
                                                      });
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: #2b91af"&gt;TimeZoneInfo&lt;/span&gt;.ConvertTime(currentLocalTime, timeZoneInfo), result);
}
&lt;/font&gt;&lt;/pre&gt;


&lt;p&gt; &lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:F60BB8FA-6F02-4999-8F5E-9DD4E92C4DA7:231146bc-bf73-4d5f-bd7e-83d8ef9f85c2" class="wlWriterEditableSmartContent"&gt;&lt;div&gt;&lt;a href="http://blog.petegoo.com/images/blog_petegoo_com/WindowsLiveWriter/UnitTestingWorkflow4Activities_1294C/UnitTestingActivities.zip" target="_self"&gt;UnitTestingActivities.zip&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="/blog/aggbug/40.aspx" width="1" height="1" /&gt;</content>
    </entry>
    <entry>
        <title>WF4 Services Part 2 &amp;ndash; Correlation</title>
        <link rel="alternate" type="text/html" href="http://blog.petegoo.com/blog/archive/2010/06/27/wf4-services-part-2-ndash-correlation.aspx" />
        <id>http://blog.petegoo.com/blog/archive/2010/06/27/wf4-services-part-2-ndash-correlation.aspx</id>
        <published>2010-06-27T11:13:19Z</published>
        <updated>2010-06-27T11:13:19Z</updated>
        <content type="html">&lt;p&gt;Continuing on from &lt;a href="http://blog.petegoo.com/archive/2010/06/27/wf4-services-part-1ndashthe-simple-wf-service.aspx"&gt;Part 1&lt;/a&gt; now we are going to add the Calculation operations to our stateful workflow service. First we need to look back and understand our previous operation “Start”.&lt;/p&gt;  &lt;p&gt;If you look at the &lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.activities.receive.aspx" target="_blank"&gt;Receive&lt;/a&gt; activity for the Start operation you will see that it has a property in the properties panel (F4) called &lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.activities.receive.cancreateinstance.aspx" target="_blank"&gt;CanCreateInstance&lt;/a&gt; and it is set to true. This property means that a call to this operation will start a new instance of our workflow. Up to now our service has simply started when we called the “Start” method and ended after the response was sent. This is all well and good but as I stated above we want a stateful service that will track the current value of our operations and let us perform further operations in a chaining manner. To do this our Add, Subtract, Divide and Multiply operations are not going to create new instances but simply act upon the previous return value.&lt;/p&gt;  &lt;p&gt;This poses a problem, if we can call the start operation multiple times and create multiple instance how are we going to know which instance we want when we make the subsequent calculation operations? This is where correlation comes in. Correlation is simply the method by which we direct incoming messages to the correct workflow instance. In our example we are going to use a parameter on each operation called session name. This will allow us to tag the session with a name so that we can bring up the right instance when we make subsequent calls. First we are going to need a &lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.activities.correlationhandle.aspx" target="_blank"&gt;CorrelationHandle&lt;/a&gt;. This is a special type provided by workflow which allows us to create this token so that the runtime can correlate properly.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.petegoo.com/images/blog_petegoo_com/WindowsLiveWriter/34675cca26f8_FA0B/CropperCapture%5B10%5D_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="CropperCapture[10]" border="0" alt="CropperCapture[10]" src="/blog/images/petegooc_w04_winhost_com/blog/CropperCapture%5B10%5D_thumb.jpg" width="218" height="273" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;1. At the root sequence (Sequential Service), add a variable of type &lt;strong&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.activities.correlationhandle.aspx" target="_blank"&gt;System.ServiceModel.Activities.CorrelationHandle&lt;/a&gt;&lt;/strong&gt; called “SessionNameCorrelationHandle”. You do not need to default this variable, any type that derives from &lt;strong&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.handle.aspx" target="_blank"&gt;System.Activities.Handle&lt;/a&gt;&lt;/strong&gt; will be constructed automatically by the runtime.&lt;/p&gt;  &lt;p&gt;2. Also at the root sequence add another variable called “SessionName” of type string. This is going to hold the actual session name specified on the Start operation.&lt;/p&gt;  &lt;p&gt;3. Edit the Content for the ReceiveRequest activity and add a parameter called “sessionName” of type string and assign it to the variable “SessionName”.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.petegoo.com/images/blog_petegoo_com/WindowsLiveWriter/34675cca26f8_FA0B/CropperCapture%5B12%5D_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="CropperCapture[12]" border="0" alt="CropperCapture[12]" src="/blog/images/petegooc_w04_winhost_com/blog/CropperCapture%5B12%5D_thumb.jpg" width="584" height="217" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now we need to initialize our correlation handle on the Start operation.&lt;/p&gt;  &lt;p&gt;4. On the send reply activity add another return parameter called “SessionReturn” which returns our SessionName variable.&lt;/p&gt;  &lt;p&gt;5. Also on the send reply activity, from the properties panel choose CorrelationInitializers, add the initializer to our SessionNameCorrelationHandle on the left. On the right make sure you have “Query Correlation Initializer” selected which will allow us to choose a value from the result to initialize the correlation handle.From the drop down under XPath Queries choose our SessionReturn parameter.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.petegoo.com/images/blog_petegoo_com/WindowsLiveWriter/34675cca26f8_FA0B/CropperCapture%5B23%5D_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="CropperCapture[23]" border="0" alt="CropperCapture[23]" src="/blog/images/petegooc_w04_winhost_com/blog/CropperCapture%5B23%5D_thumb.jpg" width="598" height="256" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;You do not have to use this method to initialize the correlation handle. You could also use the &lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.activities.initializecorrelation.aspx" target="_blank"&gt;InitializeCorrelation&lt;/a&gt; activity and place it after the SendReply activity, initializing from the “SessionName” variable rather than the return parameter.&lt;/p&gt;  &lt;p&gt;Next we need to add our calculation operations which can be performed as many times as we want until we choose to end the session. To do this we are going to use a &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.statements.pick.aspx" target="_blank"&gt;Pick&lt;/a&gt; activity to host 4 Receive and SendReply pairs (Add, Subtract, Divide, Multiply). The &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.statements.pick.aspx" target="_blank"&gt;Pick&lt;/a&gt; activity is kind of like a parallel which contains multiple &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.statements.pickbranch.aspx" target="_blank"&gt;Pick Branches&lt;/a&gt;. Each Branch has a trigger and an action. Once the trigger in a branch has been satisfied the other branches are all cancelled and the action for the triggered branch is executed. We are going to use the Trigger part of each branch to host an infinite loop of the Receive/SendReply pairs so that they continue to accept subsequent calls.A final Pick branch will contain the End operation which will Stop the Calculator session and free up the correlation handle.&lt;/p&gt;  &lt;p&gt;6. Add a &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.statements.pick.aspx" target="_blank"&gt;Pick&lt;/a&gt; activity at the end of our current workflow. Rename Branch1 to “Add Branch” by changing the title.Drag a While activity into the Trigger of "Add Branch”, set the condition to True so that it repeats indefinitely. &lt;/p&gt;  &lt;p&gt;7. Drag a ReceiveAndSendReply from the toolbox into the While activity’s Body, change the operation name to “Add”. In the sequence created by the ReceiveAndSendReply add an Int32 variable called X. Change the content of the Receive(Add)to Parameters with an Int32 parameter called X and a string parameter called SessionName. Assign the X parameter to our X variable.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.petegoo.com/images/blog_petegoo_com/WindowsLiveWriter/34675cca26f8_FA0B/CropperCapture%5B16%5D_4.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="CropperCapture[16]" border="0" alt="CropperCapture[16]" src="/blog/images/petegooc_w04_winhost_com/blog/CropperCapture%5B16%5D_thumb_1.jpg" width="451" height="168" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;8. To setup the correlation click on the CorrelatesOn property in the properties panel (F4) of the Receive(Add) activity. Change the CorrelatesWith to point to our SessionNameCorrelationHandle. Choose the property SessionName. Make sure the Key matches the key used in step 5.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.petegoo.com/images/blog_petegoo_com/WindowsLiveWriter/34675cca26f8_FA0B/CropperCapture%5B20%5D_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" class="wlDisabledImage" title="CropperCapture[20]" border="0" alt="CropperCapture[20]" src="/blog/images/petegooc_w04_winhost_com/blog/CropperCapture%5B20%5D_thumb.jpg" width="397" height="222" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;9. In between the Receive(Add) and it’s SendReply activity drag an Assign activity. In the To section enter the Value variable and in the right hand side enter the expression “Value + X”.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.petegoo.com/images/blog_petegoo_com/WindowsLiveWriter/34675cca26f8_FA0B/CropperCapture%5B18%5D_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="CropperCapture[18]" border="0" alt="CropperCapture[18]" src="/blog/images/petegooc_w04_winhost_com/blog/CropperCapture%5B18%5D_thumb.jpg" width="259" height="407" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;10. On the SendReplyToReceive of the Add pair change the content to return parameters with a single parameter Result with a value of our Value variable.&lt;/p&gt;  &lt;p&gt;11. Delete Branch2 from the pick and lets test what we have with CTRL+F5. Open the Start operation and enter an integer value and a string session name then invoke. Open the Add method and repeat the same name with another integer.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.petegoo.com/images/blog_petegoo_com/WindowsLiveWriter/34675cca26f8_FA0B/CropperCapture%5B21%5D_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="CropperCapture[21]" border="0" alt="CropperCapture[21]" src="/blog/images/petegooc_w04_winhost_com/blog/CropperCapture%5B21%5D_thumb.jpg" width="587" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.petegoo.com/images/blog_petegoo_com/WindowsLiveWriter/34675cca26f8_FA0B/CropperCapture%5B22%5D_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="CropperCapture[22]" border="0" alt="CropperCapture[22]" src="/blog/images/petegooc_w04_winhost_com/blog/CropperCapture%5B22%5D_thumb.jpg" width="587" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;12. Now Copy and paste the Add branch to create a Subtract, Divide and Multiply branches changing the operation names and assign activities as necessary. Note that you will need to go into each branch and change the CorrelatesOn property of each Receive activity so that the XPath is correct and not pointing to the Add method. Also remember to keep the Key the same as step 5. You will need to use the “\” integer divide operator of VB to do the divide assign statement.&lt;/p&gt;  &lt;p&gt;13. Finally we need to add a branch for our end activity. This will be another Pick branch but this time there will be no While loop so that when it gets called, the other branches will get cancelled and the workflow will complete. Drag on a new PickBranch, Drag a ReceiveAndSendReply into the trigger, change the operation name, add the SessionName parameter to the content and set the correlation like the others.&lt;/p&gt;  &lt;p&gt;So now we have created our stateful service with correlation on a session name. You should note that you cannot use the session name after calling End just like you could not use a random new session name on any operation but Start.&lt;/p&gt;  &lt;p&gt;In the next part we will look at what happens in the service host to enable these services endpoints to be created.&lt;/p&gt;  &lt;p&gt;Code for this post is attached below.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:F60BB8FA-6F02-4999-8F5E-9DD4E92C4DA7:09fa6981-ea56-4799-af28-d8d09be37bca" class="wlWriterEditableSmartContent"&gt;&lt;div&gt;&lt;a href="http://blog.petegoo.com/images/blog_petegoo_com/WindowsLiveWriter/34675cca26f8_FA0B/CalculatorWorkflowService.zip" target="_blank"&gt;CalculatorWorkflowService.zip&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="/blog/aggbug/39.aspx" width="1" height="1" /&gt;</content>
    </entry>
    <entry>
        <title>WF4 Services Part 1&amp;ndash;The simple WF Service</title>
        <link rel="alternate" type="text/html" href="http://blog.petegoo.com/blog/archive/2010/06/27/wf4-services-part-1ndashthe-simple-wf-service.aspx" />
        <id>http://blog.petegoo.com/blog/archive/2010/06/27/wf4-services-part-1ndashthe-simple-wf-service.aspx</id>
        <published>2010-06-27T08:56:42Z</published>
        <updated>2010-06-27T08:56:42Z</updated>
        <content type="html">&lt;p&gt;I thought I’d do a series of posts on workflow services. There are plenty of resources out there already on how to build workflows and activities although not a huge amount has been said about workflow services. In my opinion this is the real power of workflow and its where WF4 really comes into its own. In fact I’m going to presume that you’ve played a little with workflow and understand what an activity is, that’s about it.&lt;/p&gt;  &lt;p&gt;Over the series we’re going to be building a calculator service which performs integer operations in a stateful way so that subsequent operations build on the previous output.&lt;/p&gt;  &lt;p&gt;1. Open Visual Studio 2010&lt;/p&gt;  &lt;p&gt;2. Create a New Project of Type &lt;strong&gt;Visual C#/Workflow/WCF Workflow Service Application&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.petegoo.com/images/blog_petegoo_com/WindowsLiveWriter/23b80cd38c61_D605/CropperCapture%5B3%5D_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" class="wlDisabledImage" title="CropperCapture[3]" border="0" alt="CropperCapture[3]" src="/blog/images/petegooc_w04_winhost_com/blog/CropperCapture%5B3%5D_thumb.jpg" width="500" height="318" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;3. The project template should create the following workflow for you.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.petegoo.com/images/blog_petegoo_com/WindowsLiveWriter/23b80cd38c61_D605/CropperCapture%5B4%5D_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" class="wlDisabledImage" title="CropperCapture[4]" border="0" alt="CropperCapture[4]" src="/blog/images/petegooc_w04_winhost_com/blog/CropperCapture%5B4%5D_thumb.jpg" width="234" height="284" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;So what are these activities? Well if you’ve read any other intros to workflow you will know that the outer activity is a Sequence. Simply put, the child activities enclosed in a sequence are executed sequentially, of course. The activities labelled ReceiveRequest and SendResponse are Receive and SendReply activities. Typically found together these activities are the basis of creating any workflow service. Each pair represents an operation on a service contract. The operation name as shown here is GetData and the “Content” on each of the activities is the definition of the Request or Response message.&lt;/p&gt;  &lt;p&gt;4. Next we’re going to change the operation name and the message contents so that we get an Start operation for our Calculator service which accepts and integer.&lt;/p&gt;  &lt;p&gt;The Start operation is going to take an integer value and begin our calculator service. From this integer we can then perform as many operations as we like acting on the current state. To store the current state we need to first create a “Value” variable. Click on the Variables button at the bottom of the designer and add a new Int32 variable called “Value”. You can delete the data variable as we will not need it.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.petegoo.com/images/blog_petegoo_com/WindowsLiveWriter/23b80cd38c61_D605/CropperCapture%5B5%5D_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" class="wlDisabledImage" title="CropperCapture[5]" border="0" alt="CropperCapture[5]" src="/blog/images/petegooc_w04_winhost_com/blog/CropperCapture%5B5%5D_thumb.jpg" width="584" height="110" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;On the ReceiveRequest activity change the OperationName to “Start”. Click View Message next to the Content of the ReceiveRequest activity, change the mode to “Parameters” and add a new parameter called value of type integer and assign it to our “Value” variable.    &lt;br /&gt;    &lt;br /&gt;&lt;a href="http://blog.petegoo.com/images/blog_petegoo_com/WindowsLiveWriter/23b80cd38c61_D605/CropperCapture%5B6%5D_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" class="wlDisabledImage" title="CropperCapture[6]" border="0" alt="CropperCapture[6]" src="/blog/images/petegooc_w04_winhost_com/blog/CropperCapture%5B6%5D_thumb.jpg" width="609" height="203" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;On the “SendResponse” activity change the message content to “Parameters” and add a “Result “ parameter with the value as below:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.petegoo.com/images/blog_petegoo_com/WindowsLiveWriter/23b80cd38c61_D605/CropperCapture%5B7%5D_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" class="wlDisabledImage" title="CropperCapture[7]" border="0" alt="CropperCapture[7]" src="/blog/images/petegooc_w04_winhost_com/blog/CropperCapture%5B7%5D_thumb.jpg" width="617" height="206" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;5. Run the service by hitting CTRL+F5, this will start the WCF Test Client. Double click the Start method on the left hand pane and enter an integer value then Invoke. You should see the result of our service operation as below;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.petegoo.com/images/blog_petegoo_com/WindowsLiveWriter/23b80cd38c61_D605/CropperCapture%5B9%5D_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" class="wlDisabledImage" title="CropperCapture[9]" border="0" alt="CropperCapture[9]" src="/blog/images/petegooc_w04_winhost_com/blog/CropperCapture%5B9%5D_thumb.jpg" width="699" height="282" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;You can notice that we have created a service with the contract name “IService” which has a single operation “Start” accepting an integer value and returning a string. This is really no different than creating a normal WCF service with a contract interface and an implementation class that returns a string like the following:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Service1 &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;IService1 &lt;/span&gt;{
    &lt;span style="color: blue"&gt;public string &lt;/span&gt;Start(&lt;span style="color: blue"&gt;int &lt;/span&gt;value) {
        &lt;span style="color: blue"&gt;return string&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;"Calculation session started with value {0}"&lt;/span&gt;, value);
    }
}

[&lt;span style="color: #2b91af"&gt;ServiceContract&lt;/span&gt;]
&lt;span style="color: blue"&gt;public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IService1 &lt;/span&gt;{

    [&lt;span style="color: #2b91af"&gt;OperationContract&lt;/span&gt;]
    &lt;span style="color: blue"&gt;string &lt;/span&gt;Start(&lt;span style="color: blue"&gt;int &lt;/span&gt;value);
}&lt;/pre&gt;

&lt;p&gt;So how do we change the contract name? Click the Receive activity and then on the Properties panel (F4) change the ServiceContractName property to another namespace and name combination.&lt;/p&gt;

&lt;p&gt;So that was how to quickly create a WF4 service. Next we’ll add the calculation operations and do some correlation.&lt;/p&gt;

&lt;p&gt;The source for the steps in this post is attached below.&lt;/p&gt;

&lt;p&gt;
  &lt;/p&gt;&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:F60BB8FA-6F02-4999-8F5E-9DD4E92C4DA7:942115ca-79c2-43be-9a16-53056b2c24c6" class="wlWriterEditableSmartContent"&gt;&lt;div&gt;&lt;a href="http://blog.petegoo.com/images/blog_petegoo_com/WindowsLiveWriter/23b80cd38c61_D605/CalculatorWorkflowService.zip" target="_blank"&gt;CalculatorWorkflowService.zip&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="/blog/aggbug/38.aspx" width="1" height="1" /&gt;</content>
    </entry>
    <entry>
        <title>Hello again</title>
        <link rel="alternate" type="text/html" href="http://blog.petegoo.com/blog/archive/2010/06/27/hello-again.aspx" />
        <id>http://blog.petegoo.com/blog/archive/2010/06/27/hello-again.aspx</id>
        <published>2010-06-27T07:11:20Z</published>
        <updated>2010-06-27T07:11:20Z</updated>
        <content type="html">&lt;p&gt;So, I’ve been pretty bad at updating my blog recently, and answering comments / deleting spam.&lt;/p&gt;  &lt;p&gt;I’ve been spending most of my time in Workflow 4 recently so I think I’ll do a series or 2 of posts on that. Hopefully someone finds it interesting / useful.&lt;/p&gt;&lt;img src="/blog/aggbug/37.aspx" width="1" height="1" /&gt;</content>
    </entry>
    <entry>
        <title>Using JSON.Net to eval json into a dynamic variable in C#</title>
        <link rel="alternate" type="text/html" href="http://blog.petegoo.com/blog/archive/2009/10/27/using-json.net-to-eval-json-into-a-dynamic-variable-in.aspx" />
        <id>http://blog.petegoo.com/blog/archive/2009/10/27/using-json.net-to-eval-json-into-a-dynamic-variable-in.aspx</id>
        <published>2009-10-27T10:22:13Z</published>
        <updated>2009-10-27T10:22:13Z</updated>
        <content type="html">&lt;p&gt;So I thought this would be possible and finally decided to give it a shot in 2010 Beta 2. It turns a bunch of JSON into an &lt;a href="http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject(VS.100).aspx"&gt;ExpandoObject&lt;/a&gt; using &lt;a title="Json.Net" href="http://json.codeplex.com/"&gt;JSON.Net&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Needs cleaning up but not too bad.&lt;/p&gt;  &lt;div class="Section1"&gt;   &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;        [&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; DeserializeTestObjectToDynamic(){&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: #2b91af"&gt;TestObject&lt;/span&gt; testObject = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;TestObject&lt;/span&gt;() {&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                FirstName = &lt;span style="color: #a31515"&gt;"Peter"&lt;/span&gt;,&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                LastName = &lt;span style="color: #a31515"&gt;"Goodman"&lt;/span&gt;,&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                DateOfBirth = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;(&lt;span style="color: brown"&gt;1979&lt;/span&gt;, &lt;span style="color: brown"&gt;2&lt;/span&gt;, &lt;span style="color: brown"&gt;3&lt;/span&gt;),&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                Child = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;TestChildObject&lt;/span&gt; {&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                    Line1 = &lt;span style="color: #a31515"&gt;"child line 1"&lt;/span&gt;,&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                    Line2 = &lt;span style="color: #a31515"&gt;"child line 2"&lt;/span&gt;,&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                    Line3 = &lt;span style="color: #a31515"&gt;"child line 3"&lt;/span&gt;,&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                    City = &lt;span style="color: #a31515"&gt;"child city"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                },&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt; &lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                Children = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Collection&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;TestChildObject&lt;/span&gt;&amp;gt;() {&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                    &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;TestChildObject&lt;/span&gt;() { &lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                    Line1 = &lt;span style="color: #a31515"&gt;"children 1 line 1"&lt;/span&gt;,&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                    Line2 = &lt;span style="color: #a31515"&gt;"children 1 line 2"&lt;/span&gt;,&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                    Line3 = &lt;span style="color: #a31515"&gt;"children 1 line 3"&lt;/span&gt;,&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                    City = &lt;span style="color: #a31515"&gt;"children 1 city"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                },&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;TestChildObject&lt;/span&gt;() { &lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                    Line1 = &lt;span style="color: #a31515"&gt;"children 2 line 1"&lt;/span&gt;,&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                    Line2 = &lt;span style="color: #a31515"&gt;"children 2 line 2"&lt;/span&gt;,&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                    Line3 = &lt;span style="color: #a31515"&gt;"children 2 line 3"&lt;/span&gt;,&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                    City = &lt;span style="color: #a31515"&gt;"children 2 city"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                }&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                             }&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt; &lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            };&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt; &lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: green"&gt;// Get our json string &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: blue"&gt;string&lt;/span&gt; json = &lt;span style="color: #2b91af"&gt;JsonConvert&lt;/span&gt;.SerializeObject(testObject);&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt; &lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: green"&gt;// Create the json.Net Linq object for our json string&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: #2b91af"&gt;JObject&lt;/span&gt; jsonObject = &lt;span style="color: #2b91af"&gt;JObject&lt;/span&gt;.Parse(json);&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt; &lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: green"&gt;// eval into an expando&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: blue"&gt;dynamic&lt;/span&gt; dynObject = ConvertJTokenToObject(jsonObject);&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt; &lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt; &lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt; &lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsNotNull(dynObject);&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt; &lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsNotInstanceOfType(dynObject, &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;TestObject&lt;/span&gt;));&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsInstanceOfType(dynObject, &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ExpandoObject&lt;/span&gt;));&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt; &lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(testObject.FirstName, dynObject.FirstName);&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(testObject.LastName, dynObject.LastName);&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(testObject.DateOfBirth, dynObject.DateOfBirth);&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt; &lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsNotNull(dynObject.Child);&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(testObject.Child.Line1, dynObject.Child.Line1);&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(testObject.Child.Line2, dynObject.Child.Line2);&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(testObject.Child.Line3, dynObject.Child.Line3);&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt; &lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsNotNull(dynObject.Children);&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(testObject.Children.Count, dynObject.Children.Length);&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: blue"&gt;for&lt;/span&gt; (&lt;span style="color: blue"&gt;int&lt;/span&gt; i = &lt;span style="color: brown"&gt;0&lt;/span&gt;; i &amp;lt; testObject.Children.Count; i++) {&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(testObject.Children[i].Line1, dynObject.Children[i].Line1);&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(testObject.Children[i].Line2, dynObject.Children[i].Line2);&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(testObject.Children[i].Line3, dynObject.Children[i].Line3);&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            }&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;        }&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt; &lt;/p&gt; &lt;/div&gt;  &lt;div class="Section1"&gt;   &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;object&lt;/span&gt; ConvertJTokenToObject(&lt;span style="color: #2b91af"&gt;JToken&lt;/span&gt; token) {&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (token &lt;span style="color: blue"&gt;is&lt;/span&gt; &lt;span style="color: #2b91af"&gt;JValue&lt;/span&gt;) { &lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                &lt;span style="color: blue"&gt;return&lt;/span&gt; ((&lt;span style="color: #2b91af"&gt;JValue&lt;/span&gt;)token).Value;&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            }&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (token &lt;span style="color: blue"&gt;is&lt;/span&gt; &lt;span style="color: #2b91af"&gt;JObject&lt;/span&gt;) { &lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                &lt;span style="color: #2b91af"&gt;ExpandoObject&lt;/span&gt; expando = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ExpandoObject&lt;/span&gt;();&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                (&lt;span style="color: blue"&gt;from&lt;/span&gt; childToken &lt;span style="color: blue"&gt;in&lt;/span&gt; ((&lt;span style="color: #2b91af"&gt;JToken&lt;/span&gt;)token) &lt;span style="color: blue"&gt;where&lt;/span&gt; childToken &lt;span style="color: blue"&gt;is&lt;/span&gt; &lt;span style="color: #2b91af"&gt;JProperty&lt;/span&gt; &lt;span style="color: blue"&gt;select&lt;/span&gt; childToken &lt;span style="color: blue"&gt;as&lt;/span&gt; &lt;span style="color: #2b91af"&gt;JProperty&lt;/span&gt;).ToList().ForEach(property =&amp;gt; {&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                    ((&lt;span style="color: #2b91af"&gt;IDictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;)expando).Add(property.Name, ConvertJTokenToObject(property.Value));&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                });&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                &lt;span style="color: blue"&gt;return&lt;/span&gt; expando;&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            }&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt;(token &lt;span style="color: blue"&gt;is&lt;/span&gt; &lt;span style="color: #2b91af"&gt;JArray&lt;/span&gt;){&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                &lt;span style="color: blue"&gt;object&lt;/span&gt;[] array = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: blue"&gt;object&lt;/span&gt;[((&lt;span style="color: #2b91af"&gt;JArray&lt;/span&gt;)token).Count];&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                &lt;span style="color: blue"&gt;int&lt;/span&gt; index = &lt;span style="color: brown"&gt;0&lt;/span&gt;;&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;JToken&lt;/span&gt; arrayItem &lt;span style="color: blue"&gt;in&lt;/span&gt; ((&lt;span style="color: #2b91af"&gt;JArray&lt;/span&gt;)token)) {&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                    array[index] = ConvertJTokenToObject(arrayItem);&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                    index++;&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                }&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;                &lt;span style="color: blue"&gt;return&lt;/span&gt; array;&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            }&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;            &lt;span style="color: blue"&gt;throw&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ArgumentException&lt;/span&gt;(&lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;"Unknown token type '{0}'"&lt;/span&gt;, token.GetType()), &lt;span style="color: #a31515"&gt;"token"&lt;/span&gt;);&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt;        }&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: normal; margin-bottom: 0pt" class="MsoNormal"&gt;&lt;span style="font-family: consolas; font-size: 9.5pt"&gt; &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt; &lt;/p&gt; &lt;/div&gt;&lt;img src="/blog/aggbug/36.aspx" width="1" height="1" /&gt;</content>
    </entry>
    <entry>
        <title>Unit Testing Visual Studio DSL Tools</title>
        <link rel="alternate" type="text/html" href="http://blog.petegoo.com/blog/archive/2009/09/15/unit-testing-visual-studio-dsl-tools.aspx" />
        <id>http://blog.petegoo.com/blog/archive/2009/09/15/unit-testing-visual-studio-dsl-tools.aspx</id>
        <published>2009-09-15T01:18:17Z</published>
        <updated>2009-09-15T01:18:17Z</updated>
        <content type="html">&lt;p&gt;I’ve been meaning to post this entry for a while now so while I wait for a 2010 beta install to complete…. &lt;/p&gt;  &lt;p&gt;For a long time I thought it wasn’t possible to unit test DSL Tools projects easily. Due to the nature of the environment it is sometimes difficult to see how unit testing is possible. The model elements are put in a partition in a store and all the partial classes, rules etc are very tightly coupled.&lt;/p&gt;  &lt;p&gt;It wasn’t until I wanted to write a use-case oriented management layer on top of our multiple DSLs that I first thought of how it was possible. I wanted to a find way to test that the abstracted co-ordination methods on the management layer would create the expected model elements and what I got was an accidental pattern for testing DSL tools.&lt;/p&gt;  &lt;p&gt;The main trick lies in creating a model context that will hold your store, model root and handle transactions.&lt;/p&gt;  &lt;p&gt;The ModelingTestContext class:&lt;/p&gt;  &lt;div style="font-family: courier new; background: white; color: black; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ModelingTestContext&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;IDisposable&lt;/span&gt; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;    &lt;span style="color: blue"&gt;private&lt;/span&gt; Transaction tx;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;    &lt;span style="color: blue"&gt;private&lt;/span&gt; Store store;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; ModelingTestContext() {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;        store = &lt;span style="color: blue"&gt;new&lt;/span&gt; Store();&lt;/p&gt;    &lt;p style="margin: 0px"&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;        &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt; domainModelType = &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(MyCompany.DomainModelDslDomainModel);&lt;/p&gt;    &lt;p style="margin: 0px"&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;        &lt;span style="color: green"&gt;// Create a new store to deserialize the instance to. &lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;        &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;[] metaTypes = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;[]&lt;/p&gt;    &lt;p style="margin: 0px"&gt;                               {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;                                   &lt;span style="color: blue"&gt;typeof&lt;/span&gt; (CoreDesignSurfaceDomainModel),&lt;/p&gt;    &lt;p style="margin: 0px"&gt;                                   domainModelType &lt;/p&gt;    &lt;p style="margin: 0px"&gt;                               };&lt;/p&gt;    &lt;p style="margin: 0px"&gt;        &lt;span style="color: green"&gt;// Load these types into the store, so that it knows about them for deserialization &lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;        store.LoadDomainModels(metaTypes);&lt;/p&gt;    &lt;p style="margin: 0px"&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;        tx = store.TransactionManager.BeginTransaction(&lt;span style="color: #a31515"&gt;"Domain Modeling Test Context"&lt;/span&gt;);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;        domainModelRoot = &lt;span style="color: blue"&gt;new&lt;/span&gt; MyModelRoot(store);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;    }&lt;/p&gt;    &lt;p style="margin: 0px"&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; MyModelRoot DomainModelRoot {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;get&lt;/span&gt; { &lt;span style="color: blue"&gt;return&lt;/span&gt; domainModelRoot; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;    }&lt;/p&gt;    &lt;p style="margin: 0px"&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; Store Store {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;get&lt;/span&gt; { &lt;span style="color: blue"&gt;return&lt;/span&gt; store; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;    }&lt;/p&gt;    &lt;p style="margin: 0px"&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; CommitChanges() {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;        tx.Commit();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;        tx = store.TransactionManager.BeginTransaction(&lt;span style="color: #a31515"&gt;"Domain Modeling Test Context"&lt;/span&gt;);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;    }&lt;/p&gt;    &lt;p style="margin: 0px"&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Dispose() {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;if&lt;/span&gt;(tx != &lt;span style="color: blue"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; tx.IsActive) {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;            tx.Rollback();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;        }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;    }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;This class will create the model root inside the store and manage transactions for us. We next need to start writing a test.&lt;/p&gt;  &lt;div style="font-family: courier new; background: white; color: black; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;[TestMethod]&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; CreateAssociationSingleMultiplicity() {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;    &lt;span style="color: blue"&gt;using&lt;/span&gt; (ModelingTestContext domainContext = &lt;span style="color: blue"&gt;new&lt;/span&gt; ModelingTestContext()) {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;        domainContext.DomainModelRoot.Namespace = &lt;span style="color: #a31515"&gt;"Aderant.Test.DomainFoo"&lt;/span&gt;;&lt;/p&gt;    &lt;p style="margin: 0px"&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;        DomainComponent clientDc = domainContext.CreateDomainComponent(&lt;span style="color: #a31515"&gt;"Client"&lt;/span&gt;);&lt;/p&gt;    &lt;p style="margin: 0px"&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;        DomainComponent addressDc = domainContext.CreateDomainComponent(&lt;span style="color: #a31515"&gt;"Address"&lt;/span&gt;);&lt;/p&gt;    &lt;p style="margin: 0px"&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;        AssociationLink link = clientDc.AssociateWith(addressDc, Multiplicity.One);&lt;/p&gt;    &lt;p style="margin: 0px"&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;        domainContext.CommitChanges();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;        Assert.AreEqual(addressDc.Name, link.TargetRoleName);&lt;/p&gt;    &lt;p style="margin: 0px"&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;    }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;We create a context inside a using block so that we can clean up the transaction when the test completes. In this test I have added extension methods to the domain context and the DomainComponent class to support the common scenarios I used in testing like &lt;em&gt;CreateDomainComponent &lt;/em&gt;and &lt;em&gt;AssociationWith&lt;/em&gt;, allowing me to encapsulate common behavior. These extension methods can then be moved to become behavior of the model or the management API. Therefore over time you provide better API functionality which is tested.&lt;/p&gt;  &lt;p&gt;Now some people would call this integration testing instead of unit testing…..fair enough. Also some would say that the extension methods and the test context for that matter are making the tests brittle as DRY does not apply to unit testing, I would disagree as otherwise these tests would become unmanageable.&lt;/p&gt;  &lt;p&gt;I hope you find this useful.&lt;/p&gt;  &lt;p&gt;Pete&lt;/p&gt;&lt;img src="/blog/aggbug/35.aspx" width="1" height="1" /&gt;</content>
    </entry>
</feed>System.Web.HttpWriter