﻿<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
  <channel>
    <title>bloggingonit.com -- IT Blog Feeds Consolidated</title>
    <link>http://www.bloggingonit.com</link>
    <description>IT Blog Feeds Consolidated</description>
    <copyright>Copyright 2006 bloggingonit.com</copyright>
    <language>en-us</language>
    <lastBuildDate>Tue, 21 Feb 2006 17:25:21 GMT</lastBuildDate>
    <category>IT Blogs</category>
    <ttl>60</ttl>
    <image>
      <url>http://www.bloggingonit.com/logo.gif</url>
      <title>bloggingonit.com</title>
      <link>http://www.bloggingonit.com/</link>
    </image>
    <item>
      <title>Eagerness to fail</title>
      <link>http://feedproxy.google.com/~r/igloocoder/~3/Qw70CFsGlYc/eagerness-to-fail.aspx</link>
      <description>&lt;p&gt;If your developers are eagerly taking blame for failures on your project they’re either:&lt;/p&gt;  &lt;p&gt;a) buying into the concept of collective code ownership and have a commitment to quality    &lt;br /&gt;     or     &lt;br /&gt;b) are trying to get blamed for everything so that they can be fired and rid of your place of employ.&lt;/p&gt;&lt;img src="http://igloocoder.com/aggbug/1461.aspx" width="1" height="1"/&gt;</description>
      <guid>http://igloocoder.com/archive/2011/10/25/eagerness-to-fail.aspx</guid>
      <pubDate>Tue, 25 Oct 2011 13:10:39 +0000</pubDate>
      <category>Experience</category>
    </item>
    <item>
      <title>PostSharp Training</title>
      <link>http://feedproxy.google.com/~r/igloocoder/~3/JhifsknpBI8/postsharp-training.aspx</link>
      <description>&lt;p&gt;I’ve hooked up with the fine folks over at &lt;a rel="nofollow"&gt;SharpCrafters&lt;/a&gt; to build some training materials for their AOP product PostSharp. Starting in January of 2012 we will be &lt;a rel="nofollow" target="_blank" href="http://www.sharpcrafters.com/blog/post/Announcing-PostSharp-Training.aspx"&gt;offering training on the use of PostSharp&lt;/a&gt; for all your Aspect Oriented Programming needs. I’m currently working on writing the materials and every day I’m finding more interesting little corners of the tool. I’m really looking forward to some of the things that Gael has in store for v3 of it.&lt;/p&gt;  &lt;p&gt;If you’re interested in getting some training on PostSharp, shoot me an email at training@igloocoder.com.&lt;/p&gt;&lt;img src="http://igloocoder.com/aggbug/1460.aspx" width="1" height="1"/&gt;</description>
      <guid>http://igloocoder.com/archive/2011/10/03/postsharp-training.aspx</guid>
      <pubDate>Mon, 03 Oct 2011 20:07:43 +0000</pubDate>
    </item>
    <item>
      <title>Using AutoCompleteTextView and SimpleCursorAdapter</title>
      <link>http://www.opgenorth.net/2011/09/06/using-autocompletetextview-and-simplecursoradapter-2/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=using-autocompletetextview-and-simplecursoradapter-2</link>
      <description>I have a simple little pet project (for Android), and one of the things I wanted to do was to to have a text field that would show me previous values as I typed in the text box (see screenshot below). Of course, this control is already a part of the Android SDK &amp;#8211; it&amp;#8217;s [...]</description>
      <guid>http://www.opgenorth.net/?p=372</guid>
      <pubDate>Wed, 07 Sep 2011 03:30:09 +0000</pubDate>
      <encoded>&lt;p&gt;I have a simple little pet project (for Android), and one of the things I wanted to do was to to have a text field that would show me previous values as I typed in the text box (see screenshot below). Of course, this control is already a part of the Android SDK &amp;#8211; it&amp;#8217;s our good friend the &lt;a rel="nofollow" target="_blank" href="http://developer.android.com/reference/android/widget/AutoCompleteTextView.html"&gt;AutoCompleteTextView&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.opgenorth.net/wp-content/uploads/2011/09/AutoCompleteTextView.png"/&gt;&lt;/p&gt;
&lt;p&gt;To populate the drop-down, I have an SQLite table called vehicle_descriptions, which looks something like the screenshot below. What I want is for a given vehicle (a value derived from another control on my Activity) to show me the value of the description column in the table.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.opgenorth.net/wp-content/uploads/2011/09/vehicle_descriptions_table.png"/&gt;&lt;/p&gt;
&lt;p&gt;At first I started out by sub-classing &lt;a rel="nofollow" target="_blank" href="http://developer.android.com/reference/android/widget/CursorAdapter.html"&gt;CursorAdapter&lt;/a&gt;, but that just seemed to be a bit to heavy. What I had worked, but it seemed like there should be a simpler way to do this. &lt;a rel="nofollow" target="_blank" href="http://developer.android.com/reference/android/widget/CursorAdapter.html"&gt;CursorAdapter&lt;/a&gt; is probably a better choice for more elaborate requirements (maybe displaying images or doing some calculations), but in this case it struck me as overkill &amp;#8211; I just wanted to do a simple lookup against a table. Turns out I was right &amp;#8211; the easy way is to just use a &lt;a rel="nofollow" target="_blank" href="http://developer.android.com/reference/android/widget/SimpleCursorAdapter.html"&gt;SimpleCursorAdapter&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;
    &amp;lt;AutoCompleteTextView android:id=&amp;quot;@+id/description&amp;quot;
                          android:completionThreshold=&amp;quot;1&amp;quot;
                          android:layout_height=&amp;quot;wrap_content&amp;quot;
                          android:layout_width=&amp;quot;fill_parent&amp;quot;
                          android:hint=&amp;quot;Trip Description (optional)&amp;quot;
                          android:lines=&amp;quot;1&amp;quot; /&amp;gt;
&lt;/pre&gt;
&lt;p&gt;To setup my control, I have created a function that I call inside onCreate() of my Activity. Here is the code, and then I will explain it in more detail:&lt;/p&gt;
&lt;pre&gt;
    private void initializeDescription() {
        _descriptionText = (AutoCompleteTextView) findViewById(R.id.description);
        final int[] to = new int[]{android.R.id.text1};
        final String[] from = new String[]{VehicleDescriptionsTable.DESCRIPTION};
        SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
                android.R.layout.simple_dropdown_item_1line,
                null,
                from,
                to);

        // This will provide the labels for the choices to be displayed in the AutoCompleteTextView
        adapter.setCursorToStringConverter(new SimpleCursorAdapter.CursorToStringConverter() {
            @Override
            public CharSequence convertToString(Cursor cursor) {
                final int colIndex = cursor.getColumnIndexOrThrow(VehicleDescriptionsTable.DESCRIPTION);
                return cursor.getString(colIndex);
            }
        });

        // This will run a query to find the descriptions for a given vehicle.
        adapter.setFilterQueryProvider(new FilterQueryProvider() {
            @Override
            public Cursor runQuery(CharSequence description) {
                String vehicle = getSelectedVehicle();
                Cursor managedCursor = _helper.getDescriptionsFor(vehicle, description.toString());
                Log.d(TAG, "Query has " + managedCursor.getCount() + " rows of description for " + vehicle);
                return managedCursor;
            }
        });

        _descriptionText.setAdapter(adapter);
    }
&lt;/pre&gt;
&lt;p&gt;So, first things first. We setup two arrays. The to[] array holds a list of resource id&amp;#8217;s that will be used to display the text values in the drop down. I just want to display the items in a list, so I used android.R.id.text1. The other array, from[] hold the name of the column that will hold the values to display. As I mentioned above, I want to show the values in the description column.&lt;/p&gt;
&lt;p&gt;After that we new up a &lt;a rel="nofollow" target="_blank" href="http://developer.android.com/reference/android/widget/SimpleCursorAdapter.html"&gt;SimpleCursorAdapter&lt;/a&gt;. The line itself should be pretty obvious. The null that we&amp;#8217;re passing into the constructor is because we don&amp;#8217;t yet have a cursor available. In this simple case, the 3rd parameter is android.R.layout.simple_dropdown_item1line will suffice. If we were making our own view for display description, then we&amp;#8217;d pass in the resource id of the control that would display the text value.&lt;/p&gt;
&lt;p&gt;After instantiating the adapter, we provide some direction as to how we should convert the cursor to a string value that can be displayed. We do this with a &lt;a rel="nofollow" target="_blank" href="http://developer.android.com/reference/android/widget/SimpleCursorAdapter.CursorToStringConverter.html"&gt;CursorStringConverter&lt;/a&gt;. All we do here is retrieve the value of the description column in the cursor as a string and return that.&lt;/p&gt;
&lt;p&gt;The final part is to use a &lt;a rel="nofollow" target="_blank" href="http://developer.android.com/reference/android/widget/FilterQueryProvider.html"&gt;FilterQueryProvider&lt;/a&gt; to get a Cursor holding the rows and columns we want to display &amp;#8211; note that I&amp;#8217;m doing this by actually running a query each time. There are probably more efficient ways to do it (and if you have a better way I&amp;#8217;d love to hear it). The line _helper.getDescriptionsFor() will return a cursor holding all the rows from my vehicle_descriptions table for a given vehicle. The user will select the vehicle from my vehicle spinner. I created the method getSelectedVehicle() as a convenience method to return the text that is selected in the spinner.&lt;/p&gt;
&lt;p&gt;And of course, the final thing is to provide the adapter to the &lt;a rel="nofollow" target="_blank" href="http://developer.android.com/reference/android/widget/AutoCompleteTextView.html"&gt;AutoCompleteTextView&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For the sake of completeness, here is what getDescriptionsFor() looks like. The _activity below is a reference to whatever Activity. The code here is should be pretty simple &amp;#8211; we just return a managedQuery from the ContentProvider for this application. Note that with our projection we return both the _id column and the description column. The &lt;a rel="nofollow" target="_blank" href="http://developer.android.com/reference/android/widget/SimpleCursorAdapter.html"&gt;SimpleCursorAdapter&lt;/a&gt; requires the _id filed be present. Anyway, without further adieu &amp;#8211; the code:&lt;/p&gt;
&lt;pre&gt;
    public Cursor getDescriptionsFor(String vehicle, String descriptionFragment) {
        String[] projection = new String[]{VehicleDescriptionsTable._ID, VehicleDescriptionsTable.DESCRIPTION};
        String[] selectionArgs = new String[]{vehicle};

        StringBuffer selection = new StringBuffer(VehicleDescriptionsTable.DESCRIPTION)
                .append(&amp;quot; LIKE '&amp;quot;)
                .append(descriptionFragment)
                .append(&amp;quot;%' AND &amp;quot;)
                .append(VehicleDescriptionsTable.VEHICLE)
                .append(&amp;quot;=?&amp;quot;);
        String sortOrder = VehicleDescriptionsTable.DESCRIPTION;

        return _activity.managedQuery(VehicleDescriptionsTable.VEHICLE_DESCRIPTION_URI,
                projection,
                selection.toString(),
                selectionArgs, sortOrder);
    }
&lt;/pre&gt;
&lt;p&gt;There you have it &amp;#8211; &lt;a rel="nofollow" target="_blank" href="http://developer.android.com/reference/android/widget/AutoCompleteTextView.html"&gt;AutoCompleteTextView&lt;/a&gt; and &lt;a rel="nofollow" target="_blank" href="http://developer.android.com/reference/android/widget/SimpleCursorAdapter.html"&gt;SimpleCursorAdapter&lt;/a&gt; together at last. &lt;/p&gt;</encoded>
    </item>
    <item>
      <title>Slide deck and code from Prairie Developers Conference 2011</title>
      <link>http://www.opgenorth.net/2011/06/16/slide-deck-and-code-from-prairie-developers-conference-2011/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=slide-deck-and-code-from-prairie-developers-conference-2011</link>
      <description>For those wanted the slide-decks and code from my talks at Prairie Developer&amp;#8217;s Conference 2011, you can find them up on GitHub. Thanks to all who attended.&amp;#160; Maybe we&amp;#8217;ll see you again next year.</description>
      <guid>http://www.opgenorth.net/2011/06/16/slide-deck-and-code-from-prairie-developers-conference-2011/</guid>
      <pubDate>Fri, 17 Jun 2011 02:06:23 +0000</pubDate>
      <encoded>&lt;p&gt;For those wanted the slide-decks and code from my talks at &lt;a rel="nofollow" target="_blank" href="http://www.prairiedevcon.com/"&gt;Prairie Developer&amp;#8217;s Conference 2011&lt;/a&gt;, you can find them up on &lt;a rel="nofollow" target="_blank" href="https://github.com/topgenorth/PrDC2011"&gt;GitHub&lt;/a&gt;. Thanks to all who attended.&amp;nbsp; Maybe we&amp;#8217;ll see you again next year.&lt;/p&gt;</encoded>
    </item>
    <item>
      <title>Professional Neglect and Clear Text Passwords</title>
      <link>http://feedproxy.google.com/~r/igloocoder/~3/8K9sHTxkLVo/professional-neglect-and-clear-text-passwords.aspx</link>
      <description>&lt;p&gt;For that past few years I’ve been the recipient of a monthly reminder from &lt;a rel="nofollow" target="_blank" href="http://www.emug.ca"&gt;Emug&lt;/a&gt; (Edmonton Microsoft User Group). The contents of that email is where the problems lay. Every month that email comes in and it contains 3 pieces of information (plus a lot of boilerplate):&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;A link to the Emug mailing list admin site&lt;a rel="nofollow" target="_blank" href="http://www.flickr.com/photos/dbelcham/5596614184/"&gt;&lt;img style="display:inline;float:right;" align="right" src="http://farm6.static.flickr.com/5185/5596614184_a22ca79565.jpg"/&gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;My username &lt;/li&gt;    &lt;li&gt;My password in clear text &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;It doesn’t take much thought to know that storing clear text password is a prime security issue. Sending those passwords in emails doesn’t make it any better. Emails can be intercepted. Systems can be hacked. It’s happened before. Just read about the &lt;a rel="nofollow" target="_blank" href="http://thenextweb.com/us/2011/01/31/plenty-of-fish-hacked-usernames-and-passwords-compromised-says-founder/"&gt;hack of PlentyOfFish.com&lt;/a&gt;. Or the &lt;a rel="nofollow" target="_blank" href="http://krebsonsecurity.com/2011/02/hbgary-federal-hacked-by-anonymous/"&gt;hack of HB Gary&lt;/a&gt;. Two things stand out in these attacks. First, PlentyOfFish stores its passwords in clear text which made it easy to compromise the entire user base once access was achieved. HB Gary (an IT security consulting firm no less) had many users who used the same password between different systems which made it easy to hop from system to system gaining different access.&lt;/p&gt;  &lt;p&gt;Most web users don’t heed advice to have a different password for every user account they create. First, it seems unreasonable to try to remember them all. Second, most people believe that using their dogs name combined with their birth date is never going to be hackable. As system designers and operators (which the Emug membership is a professional community of) we should know that we can’t do much of anything to prevent users from choosing bad passwords. We can, however take the steps to ensure that those passwords are adequately protected.&lt;/p&gt;  &lt;p&gt;So with all of that in mind I decided to call the Emug people on their password practices. I sent an email of concern to them along with a request that they take the time to do the correct professional thing with regards to their members passwords. The response I received back included…&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;I know what you're saying about the passwords though, the first one you get is randomly generated and if you ever did go on and change it to a common one then it is there within all the options you can also set it to the option of the password reminder. The option "Get password reminder email for this list?" is a user based control option and you can set that to your liking. It's in with all the digest options.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;That’s great. So basically the Emug response was “You don’t have to see that we store your password in clear text if you just go uncheck this one box”. Jeez guys, thanks. So you’re suggesting that I should feel that my password is secure just because I’m not seeing it in an email anymore? Security through naiveté?&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Most places / sites/ subscriptions now have an automated email reminder method. It does make you ponder its value but I think the focus on that this is a very low level security setting.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Okay…so because you think “most places/sites/subscription now have an automated email reminder” it’s okay for you to follow the same bad practices? Really? What happened to professionalism? Or integrity? Yah I know, that takes effort and you’re just a volunteer running a community group. Except for one little thing: the members of that community entrusted you with their passwords. There was an implied belief that you would protect those passwords in an acceptable manner. Clearly you’re not.&lt;/p&gt;  &lt;p&gt;I also ask you to enumerate “most places / sites / subscriptions” please. I don’t get an email from Google Groups, StackOverflow, etc that contains my password in clear text. I know that those are professional companies and you’re not, but remember that professionalism has nothing to do with the size or revenue of your organization.&lt;/p&gt;  &lt;p&gt;The piece of the email that really rubbed me the wrong way was this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;The mailman list serve server and application is maintained centrally not by us for the record. It is more of a self-service model and is intentionally designed for little to no maintenance or requirement to assist an end user.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;So you don’t administer the system. That’s fine.  Yes, the current system may have been designed/implemented to require as little end user support as possible. That’s fine too. Here are my beefs. You have the choice to change what tooling you’re using. I’m pretty sure that you’re able to use Google to find replacement options. It will take some time and effort to see the change through, but don’t you think the integrity of your member’s passwords is worth it?&lt;/p&gt;  &lt;p&gt;So to Brett, Colin, Ron and Simon: Please show a modicum of professionalism and take care of this issue. Since you chose not to continue the conversation with me via email, I’ve resorted to blogging. I’m submitting your mailing list email to &lt;a rel="nofollow" target="_blank" href="http://www.plaintextoffenders.com"&gt;www.plaintextoffenders.com&lt;/a&gt;. I’ll be contacting other community members in the hopes that they can get through to you. I suspect they won’t be able to, but I feel that I have a professional obligation to at least try.&lt;/p&gt;&lt;img src="http://igloocoder.com/aggbug/1459.aspx" width="1" height="1"/&gt;</description>
      <guid>http://igloocoder.com/archive/2011/04/06/professional-neglect-and-clear-text-passwords.aspx</guid>
      <pubDate>Wed, 06 Apr 2011 23:07:33 +0000</pubDate>
      <category>Leadership</category>
    </item>
    <item>
      <title>Gifts for Dogs</title>
      <link>http://www.opgenorth.net/2011/04/06/gifts-for-dogs/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=gifts-for-dogs</link>
      <description>Casey the Samoyed gets a spring gift &amp;#8211; a portable steam cleaner for small parts of your carpet.</description>
      <guid>http://www.opgenorth.net/2011/04/06/gifts-for-dogs/</guid>
      <pubDate>Wed, 06 Apr 2011 22:48:57 +0000</pubDate>
      <encoded>&lt;p&gt;&lt;img style="display:block;margin-right:auto;margin-left:auto;" alt="image" src="http://www.opgenorth.net/wp-content/uploads/2011/04/wpid-Apr_6_2011_8285.jpg"/&gt;&lt;/p&gt;
&lt;p&gt;Casey the Samoyed gets a spring gift &amp;#8211; a portable steam cleaner for small parts of your carpet.&lt;/p&gt;</encoded>
    </item>
    <item>
      <title>Picking Apart PDF with Ruby and Linux</title>
      <link>http://www.opgenorth.net/2011/03/17/picking-apart-pdf-with-ruby-and-linux/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=picking-apart-pdf-with-ruby-and-linux</link>
      <description>I ran into a curious problem for a side problem of mine where I had some information in PDF files, both text and images.&amp;#160; What I want to do is display the information from the PDF&amp;#8217;s on a mobile (Android) device.&amp;#160; PDF isn&amp;#8217;t exactly a mobile friendly format, so I got the idea use HTML.&amp;#160; [...]</description>
      <guid>http://www.opgenorth.net/?p=356</guid>
      <pubDate>Fri, 18 Mar 2011 00:09:00 +0000</pubDate>
      <encoded>&lt;p&gt;I ran into a curious problem for a side problem of mine where I had some information in PDF files, both text and images.&amp;#160; What I want to do is display the information from the PDF&amp;#8217;s on a mobile (Android) device.&amp;#160; PDF isn&amp;#8217;t exactly a mobile friendly format, so I got the idea use HTML.&amp;#160; The next trick then becomes how to get the content out of the PDF&amp;#8217;s I want into HTML.&amp;#160; Tux to the rescue!&lt;/p&gt;
&lt;p&gt;As luck would have the, the utilities pdftotext and pdfimage will allow you to extract your text and images from a PDF (respectively).&amp;#160; pdftotext was even nice enough to extract the text from the PDF and put it into an HTML document for me. (To get these on your Ubuntu box:&amp;#160;&amp;#160; sudo apt-get install xpdf-utils).&amp;#160; Once I had these apps installed, I used a bit of Ruby to automate the process &amp;#8211; I had 65 PDF&amp;#8217;s to convert and wasn&amp;#8217;t crazy about the keystrokes involved for all 65 files.&amp;#160; Net time to do all this was a comfortable couple of hours in front of my TV catching up on the backlog of shows on the PVR.&amp;#160; How is that for multi-tasking?&lt;/p&gt;
&lt;p&gt;Here is the Ruby script I wrote.&amp;#160; I welcome suggestions / improvements / enhancements / comments / cash donations / bottles of scotch:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="line_numbers"&gt;&lt;pre&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
&lt;/pre&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;pre class="ruby" style="font-family:monospace;"&gt;&lt;span style="color:#008000;font-style:italic;"&gt;#!/usr/bin/ruby&lt;/span&gt;
&lt;span style="color:#CC00FF;font-weight:bold;"&gt;Dir&lt;/span&gt;.&lt;span style="color:#9900CC;"&gt;glob&lt;/span&gt;&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#996600;"&gt;&amp;quot;*.txt&amp;quot;&lt;/span&gt;&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color:#9966CC;font-weight:bold;"&gt;do&lt;/span&gt; &lt;span style="color:#006600;font-weight:bold;"&gt;|&lt;/span&gt;file&lt;span style="color:#006600;font-weight:bold;"&gt;|&lt;/span&gt; &lt;span style="color:#CC00FF;font-weight:bold;"&gt;File&lt;/span&gt;.&lt;span style="color:#9900CC;"&gt;delete&lt;/span&gt;&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;file&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color:#9966CC;font-weight:bold;"&gt;end&lt;/span&gt;
&lt;span style="color:#CC00FF;font-weight:bold;"&gt;Dir&lt;/span&gt;.&lt;span style="color:#9900CC;"&gt;glob&lt;/span&gt;&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#996600;"&gt;&amp;quot;*.jpg&amp;quot;&lt;/span&gt;&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color:#9966CC;font-weight:bold;"&gt;do&lt;/span&gt; &lt;span style="color:#006600;font-weight:bold;"&gt;|&lt;/span&gt;file&lt;span style="color:#006600;font-weight:bold;"&gt;|&lt;/span&gt; &lt;span style="color:#CC00FF;font-weight:bold;"&gt;File&lt;/span&gt;.&lt;span style="color:#9900CC;"&gt;delete&lt;/span&gt;&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;file&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color:#9966CC;font-weight:bold;"&gt;end&lt;/span&gt;
&lt;span style="color:#CC00FF;font-weight:bold;"&gt;Dir&lt;/span&gt;.&lt;span style="color:#9900CC;"&gt;glob&lt;/span&gt;&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#996600;"&gt;&amp;quot;*.pdf&amp;quot;&lt;/span&gt;&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color:#9966CC;font-weight:bold;"&gt;do&lt;/span&gt; &lt;span style="color:#006600;font-weight:bold;"&gt;|&lt;/span&gt;file&lt;span style="color:#006600;font-weight:bold;"&gt;|&lt;/span&gt;
	basename = &lt;span style="color:#CC00FF;font-weight:bold;"&gt;File&lt;/span&gt;.&lt;span style="color:#9900CC;"&gt;basename&lt;/span&gt;&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;file,&lt;span style="color:#996600;"&gt;'.*'&lt;/span&gt;&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#41;&lt;/span&gt;
	&lt;span style="color:#9966CC;font-weight:bold;"&gt;if&lt;/span&gt; &lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#CC00FF;font-weight:bold;"&gt;File&lt;/span&gt;.&lt;span style="color:#9900CC;"&gt;directory&lt;/span&gt;?&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;basename&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#41;&lt;/span&gt;
		&lt;span style="color:#CC00FF;font-weight:bold;"&gt;Dir&lt;/span&gt;.&lt;span style="color:#9900CC;"&gt;glob&lt;/span&gt;&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#996600;"&gt;&amp;quot;./#{basename}/*.*&amp;quot;&lt;/span&gt;&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color:#9966CC;font-weight:bold;"&gt;do&lt;/span&gt; &lt;span style="color:#006600;font-weight:bold;"&gt;|&lt;/span&gt;file2&lt;span style="color:#006600;font-weight:bold;"&gt;|&lt;/span&gt; &lt;span style="color:#CC00FF;font-weight:bold;"&gt;File&lt;/span&gt;.&lt;span style="color:#9900CC;"&gt;delete&lt;/span&gt;&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;file2&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color:#9966CC;font-weight:bold;"&gt;end&lt;/span&gt;
	&lt;span style="color:#9966CC;font-weight:bold;"&gt;else&lt;/span&gt;
	  &lt;span style="color:#CC00FF;font-weight:bold;"&gt;Dir&lt;/span&gt;.&lt;span style="color:#9900CC;"&gt;mkdir&lt;/span&gt; basename &lt;span style="color:#9966CC;font-weight:bold;"&gt;unless&lt;/span&gt; &lt;span style="color:#CC00FF;font-weight:bold;"&gt;File&lt;/span&gt;.&lt;span style="color:#9900CC;"&gt;directory&lt;/span&gt;?&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;basename&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#41;&lt;/span&gt;
	&lt;span style="color:#9966CC;font-weight:bold;"&gt;end&lt;/span&gt;
	&lt;span style="color:#CC0066;font-weight:bold;"&gt;system&lt;/span&gt;&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#996600;"&gt;&amp;quot;pdftotext&amp;quot;&lt;/span&gt;, &lt;span style="color:#996600;"&gt;&amp;quot;-htmlmeta&amp;quot;&lt;/span&gt;, file, &lt;span style="color:#996600;"&gt;&amp;quot;./#{basename}/#{basename}.html&amp;quot;&lt;/span&gt;&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#41;&lt;/span&gt;
	&lt;span style="color:#CC0066;font-weight:bold;"&gt;system&lt;/span&gt;&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#996600;"&gt;&amp;quot;pdfimages&amp;quot;&lt;/span&gt;, &lt;span style="color:#996600;"&gt;&amp;quot;-j&amp;quot;&lt;/span&gt;,  file, &lt;span style="color:#996600;"&gt;&amp;quot;./#{basename}/&amp;quot;&lt;/span&gt;&lt;span style="color:#006600;font-weight:bold;"&gt;&amp;#41;&lt;/span&gt;
	&lt;span style="color:#CC0066;font-weight:bold;"&gt;puts&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;Converted #{file} to text and extracted images to #{basename}.&amp;quot;&lt;/span&gt;
&lt;span style="color:#9966CC;font-weight:bold;"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;</encoded>
    </item>
    <item>
      <title>Purging your Privates (MSMQ with Powershell)</title>
      <link>http://www.opgenorth.net/2011/03/01/purging-your-privates-msmq-with-powershell/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=purging-your-privates-msmq-with-powershell</link>
      <description>A project I’m currently on makes heavy use of MSMQ and private queues.  Every so often, it’s necessary to purge messages from the queue during development. I got tired of always using the MMC snap-in to perform this task, so I whipped up this quick PowerShell script to handle the dirty work for me.  Granted, [...]</description>
      <guid>http://www.opgenorth.net/?p=353</guid>
      <pubDate>Tue, 01 Mar 2011 15:31:01 +0000</pubDate>
      <encoded>&lt;p&gt;A project I’m currently on makes heavy use of MSMQ and private queues.  Every so often, it’s necessary to purge messages from the queue during development. I got tired of always using the MMC snap-in to perform this task, so I whipped up this quick PowerShell script to handle the dirty work for me.  Granted, it’s pretty crude, but it gets the job done.  Any suggestions or improvements, feel free to let me know.&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="line_numbers"&gt;&lt;pre&gt;1
2
3
4
5
6
7
&lt;/pre&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;pre class="powershell" style="font-family:monospace;"&gt;&lt;span style="color:#800080;"&gt;$queuename&lt;/span&gt; &lt;span style="color:pink;"&gt;=&lt;/span&gt; &lt;span style="color:#800000;"&gt;&amp;quot;.&amp;#92;private$&amp;#92;myprivatequeue&amp;quot;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;&amp;#91;&lt;/span&gt;Reflection.Assembly&lt;span style="color:#000000;"&gt;&amp;#93;&lt;/span&gt;::&lt;span style="color:#800000;"&gt;LoadWithPartialName&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;System.Messaging&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color:pink;"&gt;|&lt;/span&gt; &lt;span style="color:#008080;font-weight:bold;"&gt;Out-Null&lt;/span&gt; 
&lt;span style="color:#800080;"&gt;$queue&lt;/span&gt; &lt;span style="color:pink;"&gt;=&lt;/span&gt; &lt;span style="color:#008080;font-weight:bold;"&gt;New-Object&lt;/span&gt; &lt;span style="color:#008080;font-style:italic;"&gt;-TypeName&lt;/span&gt; &lt;span style="color:#800000;"&gt;&amp;quot;System.Messaging.MessageQueue&amp;quot;&lt;/span&gt;
&lt;span style="color:#800080;"&gt;$queue&lt;/span&gt;.Path &lt;span style="color:pink;"&gt;=&lt;/span&gt; &lt;span style="color:#800080;"&gt;$queuename&lt;/span&gt;
&lt;span style="color:#800080;"&gt;$messagecount&lt;/span&gt; &lt;span style="color:pink;"&gt;=&lt;/span&gt; &lt;span style="color:#800080;"&gt;$queue&lt;/span&gt;.GetAllMessages&lt;span style="color:#000000;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;#41;&lt;/span&gt;.Length 
&lt;span style="color:#800080;"&gt;$queue&lt;/span&gt;.Purge&lt;span style="color:#000000;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;#41;&lt;/span&gt; 
&lt;span style="color:#008080;font-weight:bold;"&gt;Write-Host&lt;/span&gt; &lt;span style="color:#800000;"&gt;&amp;quot;$queuename has been purged of $messagecount messages.&amp;quot;&lt;/span&gt; &lt;span style="color:#008080;font-style:italic;"&gt;-ForegroundColor&lt;/span&gt; Yellow&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;</encoded>
    </item>
    <item>
      <title>Dropping my MVP</title>
      <link>http://www.haveyougotwoods.ca/2011/02/02/dropping-my-mvp</link>
      <description>I have decided to drop out of Microsoft’s Most Valuable Professional Program. I have decided this for many reasons. Mainly I feel the program has no value to me and that MVPs are of no value to MS. Experts MS states how they have these “experts” in the community and that are involved in the [...]</description>
      <guid>http://haveyougotwoods.com/archive/2011/02/02/Dropping-my-MVP.aspx</guid>
      <pubDate>Wed, 02 Feb 2011 16:06:11 +0000</pubDate>
      <encoded>&lt;p&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;I have decided to drop out of Microsoft’s Most Valuable Professional Program. I have decided this for many reasons. Mainly I feel the program has no value to me and that MVPs are of no value to MS. &lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;strong style=""&gt;Experts&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;MS states how they have these “experts” in the community and that are involved in the products. While I have met some really smart MVPs I have also met some that are so out to lunch on things yet MS still considers them experts. To me this completely devalues the MVP program. I am definitely no exception to this. I am a MVP in developer security yet I don’t consider myself to be an expert. Interested yes. Expert no. &lt;/p&gt;
&lt;p class="MsoNormal"&gt;The way you get in is by contributing to the community. I had done lots of this and it was really nice to get recognized for it. Once you are in you are supposed to be this expert that provides feedback to the products that MS is building. Now this is where the program breaks down.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;strong style=""&gt;Products&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Firstly most products you never hear about until it is too late. I hear about more MS technology from the mainstream media than I do from the MVP program. As a MVP who is supposed to be like an insider I thought that they would be looking to us for feedback on these technologies. But they don’t. They will take it after the product is released though but by then there are usually too many issues with the technology to be overcome.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;While some products are great there are a big few that still irritate me:&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style=""&gt; &lt;/span&gt;TFS is garbage if you have used anything else. I should never have to struggle to get things under source control as much as I have with this product. I should never have to struggle for days/weeks to install it. I should never have so much trouble configuring it or applying checkin policies. If any MVP worth their salt was asked about this then MS should know this. &lt;/p&gt;
&lt;p class="MsoNormal"&gt;MSBuild is another failed technology to me. It does not come close to the power of Nant so if I am going to pay the XML tax I will pay it with Nant. I will say that it is nice that proj files are msbuild files yet whenever I have had to customize my builds with MSBuild I want to hurt myself. At first I thought it was the learning curve but to me the product just does not meet my needs. Again if an MVP that uses a build technology was asked then MS would have known about this.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;MSTest also missed the mark to me when they said it was not geared towards people who do TDD. Really? No one else does TDD? I am the only MVP that does? I think not.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;The big one that continues to bug me is Entity Framework. At the ‘08 MVP summit a lot of the MVPs that saw it before it was announced pointed out the serious issues it has. At the ‘09 summit we were excited to see the improvements they had made but instead we were shown the same crap that was the ‘08 entity framework. This spawned off the Entity Framework Vote Of Non Confidence and finally in ’11 we have some of the changes that we said were so needed in ’08. Good job valuing the input of the people that actually have to use the crap you put out. &lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;strong style=""&gt;MS “Listens”/”Cares”&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;To me it seems that MS having MVPs is a way for MS to feel that they are in touch with the community at large. This is great for a company to do but it seems like the feedback that is given falls on deaf ears for many products. I am not saying that this is for all products though as some do really care about feedback. For the most part though it feels like any feedback given just falls into a void. When I asked for some contacts for TFS/MSBuild/MSTest I was told to send my feedback to my MVP lead and they would forward it on…. Because that is open. You want MVPs to be involved yet filtered (I felt anyways). I have had more interaction with MS staff by tweeting things that I have through the MVP program.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;The other big issue I have with MS in general is being treated like we will jump through hoops to help them succeed. There have been a number of “tech x is launching in a few weeks so build something” so we can showcase it emails I have received. Well that is great but how am I going to build a good app on a new technology with little documentation and no access to anyone at MS who can give me some accurate answers to issues? I understand that MS staff are not there to troubleshoot my application but on new/unreleased technology it would be good to have some sort of access if only an internal message board.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;There are some internal lists at MS for MVPs as well. I found out about the security one after being a security MVP&lt;span style=""&gt;  &lt;/span&gt;for OVER A YEAR. Now that I am on it…. Not much happens. There is little in the way of solicitation for feedback and there is little feedback provided. I assume this is because the security space is pretty quiet but then I am surprised to see things at the summit that I had no idea were being developed.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;The most surprising thing to me was when I told my MVP lead that I was not interested in participating in the program. The response was: “No problem.  Thanks for letting me know Dave.  Good luck in the future”. I expected maybe a bit more of a “Why?” response but I am not surprised that MS does not care about what other people think. Maybe, because I have become harder on MS that they are happy to be rid of me. Who knows.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Maybe I am being hard on the program. Our MVP lead is great and tells us that whatever we need he will make happen. Great but how about you let us know some of the things that you can do for us? If you want something like WP7 to succeed get more than 5 dev phones and let us know you have them if we want to build applications. If MS is thinking of a new technology solicit the MVPs for people that use or have an interest in the new tech and get their feedback at the START of development instead of at the end.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;strong style=""&gt;Rewards&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;The MVP award is given to those that contribute to the community. I enjoy doing this and I will continue to do this whenever I can. Unfortunately it costs a lot of time and money to contribute to the community. If I give a talk I have spent 40 to 200 hours preparing (yes 200 hours on a 1 hour talk) plus the costs to travel to another city, food, and accommodation. &lt;span style=""&gt; &lt;/span&gt;MS’s reward is a MSDN subscription and half of a hotel room if I attend the summit (there used to be more benefits but they have been rolled back to save costs). It would probably be more affordable for me to purchase an MSDN subscription on my own and stop speaking entirely. I have gained no additional work from the MVP program, no additional speaking gigs, and have not made relatively few connections to others because of the MVP program.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;strong style=""&gt;Fin&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;The program has become a black mark to me. It does not contain just experts (heck, they let me in). It does not certify that anyone has a clue about anything (and some of the MVP only lists prove this). It has not opened any doors for me. It does not help me stop MS from releasing crap that I have to work with. All it does for me is give me an MSDN subscription and another line on my resume. &lt;/p&gt;</encoded>
    </item>
    <item>
      <title>Security Trends</title>
      <link>http://www.haveyougotwoods.ca/2010/12/29/security-trends</link>
      <description>I have been around computers for most of my life and for the past ten years I have been involved in corporate IT on both the network side and the programming side. I was reflecting on some of the changes and trends over the past decade and thought I would share them. We have realized [...]</description>
      <guid>http://haveyougotwoods.com/archive/2011/01/10/Security-Trends.aspx</guid>
      <pubDate>Wed, 29 Dec 2010 22:29:46 +0000</pubDate>
      <encoded>&lt;p&gt;I have been around computers for most of my life and for the past ten years I have been involved in corporate IT on both the network side and the programming side. I was reflecting on some of the changes and trends over the past decade and thought I would share them.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We have realized that network security is important. Every organization I visit seems to have a firewall, antivirus, and windows updates turned on. Ten years ago it was every computer was connected straight to the internet with an exposed c$ share it seems like. Finally most corporate (and many home users) seem to have taken some basic security measures.
    &lt;/li&gt;
&lt;li&gt;Users still click on anything that pops up on the screen until they get the application/website to work. I have tried to educate people on this but it has become apparent to many of us in the industry that users just want things to work and it only when they go wrong that they care. For instance, my parents install every plugin they are prompted to as they feel that if it was bad their antivirus would catch it. I don&amp;#8217;t fault them for it, it is just human nature. We expect the locks on our house to keep people out when it is simple to smash a window (or cut a hole in the wall). We are coming around the corner on this one and seeing that we can&amp;#8217;t educate everyone and things need to just be more secure by default and leak less information.&lt;/li&gt;
&lt;li&gt;People care a lot more about their privacy now. People also don&amp;#8217;t realize that most places gathering information don&amp;#8217;t care about you as a person, they care about you as a demographic. Granted it is not a happy thought to know how much info about you is floating around but if it personalizes my searches and shows me advertisements for things I am interested in so what? It is only an issue (to me) if that information is used for nefarious purposes.&lt;/li&gt;
&lt;li&gt;Many more technologies are shipping with a more &amp;#8220;secure by default&amp;#8221; mentality. The *nix/bsd attitude has been like this since I can remember and Microsoft has really turned a corner and secured their products. I remember when a new client would tell us they were running an IIS server and we would just laugh, wipe the box, and install FreeBSD/Apache for them. Nowdays I only laugh when people have an Adobe product installed (we all do&amp;#8230; so ha ha). Adobe has realized that this is starting to hurt them and are making a big security push like MS did years ago. 
    &lt;/li&gt;
&lt;li&gt;Schools have not taught about security and they still don&amp;#8217;t. I see a bit of growth in this area but I feel this is incredibly lacking. Every time I give a presentation and ask how many people don&amp;#8217;t know about SQL injection someone still raises their hands. It is not acceptable to have developers that don&amp;#8217;t even know about the most basic/common security holes and how to prevent them. It is like hiring an electrician that does not know how to use a circuit breaker: they might get by for years without an incident but it is bound to happen eventually.&lt;/li&gt;
&lt;li&gt;Phishing/scams/chain letters has risen and fallen a lot. I find most people I talk to realize that people are trying to scam them (or will ask others to see if it is a scam) and that they know if they don&amp;#8217;t forward this message to ten other people a kitten will die (except for my sister). &lt;/li&gt;
&lt;li&gt;Piracy became common place. Back in the day it was technically difficult to find the software/music/movies and then crack it if necessary. Now my grandma can run a P2P client (or the vast array of other tools) to get her favorite songs. It is common place and it is sad. Not because I love big rich Hollywood types that complain about the money being stolen from them as they drive through Starbucks in a gold plated Bently. It is the fact that for such a huge market that they continually fail to make it simple to get the content we want quickly, conveniently, and be able to use it how we see fit. If I ran an ice cream store and everyone wanted paint flavored ice cream served off a piece of copper pipe you would see me at the hardware store every day. I think they are starting to get it and I hope to see some progress there so that everyone is happy (except me&amp;#8230;. until I get a gold plated Starbucks).&lt;/li&gt;
&lt;li&gt;The goal of software development was and still is for the most part to deliver working software. Security takes a huge back seat and is almost never a first class citizen. I don&amp;#8217;t see this trend changing much. The nice thing is that many languages are shipping in a more secure configuration which helps developers not leave as many gaping holes but I still feel that education is very important for developers.&lt;/li&gt;
&lt;/ol&gt;</encoded>
    </item>
    <item>
      <title>Fluent Build – Unreleased Features</title>
      <link>http://www.haveyougotwoods.ca/2010/12/24/fluent-build-unreleased-features</link>
      <description>There are some features not included with the current beta but are available if you download from source. TeamCityPlugin This is a plugin that I wrote that allows TeamCity to work with FluentBuild. TeamCity plugins are written in Java and I am not a Java developer but it seems to work quite well in my [...]</description>
      <guid>http://haveyougotwoods.com/archive/2011/01/05/Fluent-Build-Unreleased-Features.aspx</guid>
      <pubDate>Fri, 24 Dec 2010 04:45:59 +0000</pubDate>
      <encoded>&lt;p&gt;There are some features not included with the current beta but are available if you download from source.&lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:bold;"&gt;TeamCityPlugin&lt;/span&gt;&lt;br /&gt;
This is a plugin that I wrote that allows TeamCity to work with FluentBuild. TeamCity plugins are written in Java and I am not a Java developer but it seems to work quite well in my environment(s) so far but I am still not 100% confident to officially release it. &lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:bold;"&gt;BuildFileConverter&lt;/span&gt;&lt;br /&gt;
For my testing I was converting peoples NAnt scripts by hand and it started to get pretty tedious. I decided to create a really quick and dirty converter application. The application works fairly well to get the initial conversion from nant to FB. It will create your variables (and attempting to determine if they are BuildFolders or BuildArtifacts), initialize them, and create methods for each build target that you had. It does not parse build targets and convert them to FB syntax yet though.&lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:bold;"&gt;BuildUI&lt;/span&gt;&lt;br /&gt;
I always found reading output on the command line was a pain so I started working on a UI component to run builds. It is in its very early stages but it is much nicer than using most command line applications I hope.&lt;/p&gt;
&lt;p&gt;Where these features will go, I am not sure but if you want to play around with them then feel free.&lt;/p&gt;</encoded>
      <category>Uncategorized</category>
    </item>
    <item>
      <title>WIND Mobile and my Nexus One</title>
      <link>http://www.opgenorth.net/2010/12/20/wind-mobile-and-my-nexus-one/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=wind-mobile-and-my-nexus-one</link>
      <description>Just recently I switch my mobile carrier from Rogers to WIND Mobile. Their Holiday Miracle plan was just to good to pass up &amp;#8211; even paying the penalty to break my Rogers contract I will still save money in the long run. Anyway, once the number got transferred over, I didn&amp;#8217;t have a 3G connection, [...]</description>
      <guid>http://www.opgenorth.net/?p=351</guid>
      <pubDate>Tue, 21 Dec 2010 03:13:52 +0000</pubDate>
      <encoded>&lt;p&gt;Just recently I switch my mobile carrier from Rogers to &lt;a rel="nofollow" title="WIND mobile"&gt;WIND Mobile&lt;/a&gt;. Their &lt;a rel="nofollow" title="Holiday Miracle Plan" target="_blank" href="http://www2.windmobile.ca/en/Pages/unlimitedtalktextdata.aspx"&gt;Holiday Miracle plan&lt;/a&gt; was just to good to pass up &amp;#8211; even paying the penalty to break my Rogers contract I will still save money in the long run.&lt;/p&gt;
&lt;p&gt;Anyway, once the number got transferred over, I didn&amp;#8217;t have a 3G connection, even after selecting the WIND Home APN. &amp;nbsp;After a bit of google, it seems that what I had to do is to setup an APN. &amp;nbsp;In case I can&amp;#8217;t find it later, here are the APN settings:&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;APN&lt;/td&gt;
&lt;td&gt;mms.WINDmobile.ca&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Proxy&lt;/td&gt;
&lt;td&gt;&amp;lt;Not Set&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Port&lt;/td&gt;
&lt;td&gt;&amp;lt;Not Set&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Username&lt;/td&gt;
&lt;td&gt;&amp;lt;Not Set&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Password&lt;/td&gt;
&lt;td&gt;&amp;lt;Not Set&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Server&lt;/td&gt;
&lt;td&gt;&amp;lt;Not Set&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MMSC&lt;/td&gt;
&lt;td&gt;http://mms.WINDmobile.ca&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MMS proxy&lt;/td&gt;
&lt;td&gt;74.115.197.70&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MMS port&lt;/td&gt;
&lt;td&gt;8080&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MMC&lt;/td&gt;
&lt;td&gt;302&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MNC&lt;/td&gt;
&lt;td&gt;490&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authentication type&lt;/td&gt;
&lt;td&gt;&amp;lt;Not set&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;APN type&lt;/td&gt;
&lt;td&gt;mms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;After setting this up, bingo, got my 3G connection going.&lt;/p&gt;</encoded>
    </item>
    <item>
      <title>Fluent Build Beta</title>
      <link>http://www.haveyougotwoods.ca/2010/12/19/fluent-build-beta</link>
      <description>swfobject.registerObject("csSWF", "9.0.115", "/images/haveyougotwoods_com/FluentBuildDemo1_0_Beta/expressInstall.swf"); For those of you that follow me on twitter (@gotwoods is my handle) you may have seen that I have been working on a new open source project called FluentBuild which I am happy to announce is in Beta. This project has kept me quite busy lately but the core of the [...]</description>
      <guid>http://haveyougotwoods.com/archive/2010/12/19/Fluent-Build-Beta.aspx</guid>
      <pubDate>Sun, 19 Dec 2010 21:50:32 +0000</pubDate>
      <encoded>&lt;p&gt;For those of you that follow me on twitter (@gotwoods is my handle) you may have seen that I have been working on a new open source project called FluentBuild which I am happy to announce is in Beta. This project has kept me quite busy lately but the core of the app is now done.&lt;/p&gt;
&lt;p&gt;FluentBuild is a .NET fluent language around builds. It makes doing builds way easier than in Nant, MsBuild, and (in my mind) other build languages. With it you can now write a build file in C# (other language support on the way) within visual studio which allows you to get intellisense, refactoring support, and you are even able to debug your build files.&lt;/p&gt;
&lt;p&gt;The project site is &lt;a rel="nofollow"&gt;http://code.google.com/p/fluent-build/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I just finished putting together a demo video. I recorded my screen at high resolution so full screen viewing is recommended and the volume recorded a bit loud so turn down your speakers to start.&lt;/p&gt;
&lt;div id="media"&gt;                                        &lt;/div&gt; 
&lt;p&gt;&lt;/p&gt;</encoded>
      <category>General</category>
    </item>
    <item>
      <title>WCF Security – Part 1: Message &amp; Transport Security</title>
      <link>http://www.haveyougotwoods.ca/2010/12/16/wcf-security-part-1-message-transport-security</link>
      <description>WCF has a huge security component to it (as rightly it should). The technology is massively configurable to support almost any security scenario one can dream up. Unfortunately this also makes it massively hard to learn and implement successfully and many developers tend to work around the security rather than learn how to implement it [...]</description>
      <guid>http://haveyougotwoods.com/archive/2010/12/16/319.aspx</guid>
      <pubDate>Thu, 16 Dec 2010 22:00:02 +0000</pubDate>
      <encoded>&lt;p&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;WCF has a huge security component to it (as rightly it should). The technology is massively configurable to support almost any security scenario one can dream up. Unfortunately this also makes it massively hard to learn and implement successfully and many developers tend to work around the security rather than learn how to implement it correctly. With a bit of knowledge WCF security is not nearly as intimidating as one may think.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;There are several security concerns to deal with in any communication technology. The top two most common concerns&lt;span style=""&gt;  &lt;/span&gt;are: making sure that no one can read, modify, or replay a sensitive message and ensuring that a caller is authenticated&lt;span style=""&gt;  &lt;/span&gt;to use the system and authorized to access the resources they are allowed to access (and denied access to the ones they are not allowed to access of course). The other concerns are usually around Availability (i.e. making sure the service is resistant to Denial Of Service attacks) and Auditing (being able to log and monitor security events). &lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;strong style=""&gt;Message Protection&lt;br /&gt;
&lt;/strong&gt;&lt;br /&gt;
Protection of the traffic in transit is easy to use and is typically turned on by default (basicHTTPBinding has no security by default). There are two choices to make with securing traffic: Transport or Message security. Transport security relies on security builtin to the protocol you are using (e.g. HTTPS for HTTPBindings and TLS for TCP bindings). Message security lets WCF sign and encrypt messages and then sends it across the transport. &lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;strong style=""&gt;Transport Security:&lt;br /&gt;
&lt;/strong&gt;+Interoperability: Neither party in a communication need to support WS-Security specifications&lt;br /&gt;
+Potentially better performance&lt;br /&gt;
-Security is point to point. If a message is routed through an intermediary it will not be guaranteed to be secure (i.e. many load balancers accept SSL traffic, decrypt it, and send it unencrypted to a node in its array)&lt;br /&gt;
-Supports a smaller set of credentials and claims used for authentication&lt;br /&gt;
-All or nothing: A message is either encrypted or it is not&lt;br /&gt;
&lt;strong style=""&gt;&lt;br /&gt;
Message Security:&lt;/strong&gt;&lt;br /&gt;
+End to end security: message security survives being routed through intermediaries&lt;br /&gt;
+Allows partial message signing/encryption so that only messages that need protection can be protected&lt;br /&gt;
+Transport independent: Message security can be used with any transport protocol&lt;br /&gt;
+supports a large set of credentials and claims&lt;br /&gt;
-May reduce performance as each message is secured and can not take advantage of hardware acceleration&lt;br /&gt;
-Not as interoperable as both sides must implement the WS-Security specification&lt;/p&gt;
&lt;p class="MsoNormal"&gt; &lt;/p&gt;
&lt;table cellspacing="0" cellpadding="0" border="1" style="border-collapse:collapse;border:medium none;" class="MsoTableGrid"&gt;
&lt;tbody&gt;
&lt;tr style="height:15.75pt;"&gt;
&lt;td valign="top" style="border:1pt solid rgb(187, 187, 187);background:none repeat scroll 0% 0% rgb(229, 229, 229);padding:3pt;height:15.75pt;font-weight:bold;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;&lt;span style="font-size:10.5pt;color:black;"&gt;Binding &lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:1pt 1pt 1pt medium;border-style:solid solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% rgb(229, 229, 229);padding:3pt;height:15.75pt;font-weight:bold;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;&lt;span style="font-size:10.5pt;color:black;"&gt;Transport mode support   &lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:1pt 1pt 1pt medium;border-style:solid solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% rgb(229, 229, 229);padding:3pt;height:15.75pt;font-weight:bold;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;&lt;span style="font-size:10.5pt;color:black;"&gt;Message mode support &lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td width="167" valign="top" style="width:125.2pt;border-width:medium 1pt 1pt;border-style:none solid solid;border-color:windowtext windowtext;padding:0in 5.4pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;basicHTTPBinding&lt;/p&gt;
&lt;/td&gt;
&lt;td width="231" valign="top" style="width:172.95pt;border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:windowtext windowtext;padding:0in 5.4pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;HTTPS&lt;/p&gt;
&lt;/td&gt;
&lt;td width="241" valign="top" style="width:180.65pt;border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:windowtext windowtext;padding:0in 5.4pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;HTTP basic authentication&lt;br /&gt;
            WS-Security&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td width="167" valign="top" style="width:125.2pt;border-width:medium 1pt 1pt;border-style:none solid solid;border-color:windowtext windowtext;padding:0in 5.4pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;wsHTTPBinding&lt;/p&gt;
&lt;/td&gt;
&lt;td width="231" valign="top" style="width:172.95pt;border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:windowtext windowtext;padding:0in 5.4pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;HTTPS&lt;/p&gt;
&lt;/td&gt;
&lt;td width="241" valign="top" style="width:180.65pt;border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:windowtext windowtext;padding:0in 5.4pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;WS-Security&lt;br /&gt;
            SOAP message with credentials sent over HTTPS transport security&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td width="167" valign="top" style="width:125.2pt;border-width:medium 1pt 1pt;border-style:none solid solid;border-color:windowtext windowtext;padding:0in 5.4pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;wsDualHTTPBinding&lt;/p&gt;
&lt;/td&gt;
&lt;td width="231" valign="top" style="width:172.95pt;border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:windowtext windowtext;padding:0in 5.4pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;None&lt;/p&gt;
&lt;/td&gt;
&lt;td width="241" valign="top" style="width:180.65pt;border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:windowtext windowtext;padding:0in 5.4pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;WS-Security&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td width="167" valign="top" style="width:125.2pt;border-width:medium 1pt 1pt;border-style:none solid solid;border-color:windowtext windowtext;padding:0in 5.4pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;netTCPBinding&lt;/p&gt;
&lt;/td&gt;
&lt;td width="231" valign="top" style="width:172.95pt;border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:windowtext windowtext;padding:0in 5.4pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;TLS over TCP &lt;/p&gt;
&lt;/td&gt;
&lt;td width="241" valign="top" style="width:180.65pt;border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:windowtext windowtext;padding:0in 5.4pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;WS-Security&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td width="167" valign="top" style="width:125.2pt;border-width:medium 1pt 1pt;border-style:none solid solid;border-color:windowtext windowtext;padding:0in 5.4pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;netNamedPipeBinding&lt;/p&gt;
&lt;/td&gt;
&lt;td width="231" valign="top" style="width:172.95pt;border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:windowtext windowtext;padding:0in 5.4pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;Negotiated (best compatible support is used)&lt;/p&gt;
&lt;/td&gt;
&lt;td width="241" valign="top" style="width:180.65pt;border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:windowtext windowtext;padding:0in 5.4pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;None&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td width="167" valign="top" style="width:125.2pt;border-width:medium 1pt 1pt;border-style:none solid solid;border-color:windowtext windowtext;padding:0in 5.4pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;netMSMQBinding&lt;/p&gt;
&lt;/td&gt;
&lt;td width="231" valign="top" style="width:172.95pt;border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:windowtext windowtext;padding:0in 5.4pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;RC4 or AES (default is RC4). Messages signed with receiving queues   public certificate.&lt;/p&gt;
&lt;/td&gt;
&lt;td width="241" valign="top" style="width:180.65pt;border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:windowtext windowtext;padding:0in 5.4pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;WS-Security&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td width="167" valign="top" style="width:125.2pt;border-width:medium 1pt 1pt;border-style:none solid solid;border-color:windowtext windowtext;padding:0in 5.4pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;wsFederationHttpBinding&lt;/p&gt;
&lt;/td&gt;
&lt;td width="231" valign="top" style="width:172.95pt;border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:windowtext windowtext;padding:0in 5.4pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;HTTPS&lt;/p&gt;
&lt;/td&gt;
&lt;td width="241" valign="top" style="width:180.65pt;border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:windowtext windowtext;padding:0in 5.4pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;WS-Security&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p class="MsoNormal"&gt; &lt;/p&gt;
&lt;p class="MsoNormal"&gt;There are also a few other approaches as well. There is the hybrid TransportWithMessageCredential which the client credentials are provided at the message level and the remainder (the message itself and service authentication) is secured by the transport. The other type is TransportCredentialOnly which is ONLY for basicHTTPBinding that does mutual authentication at the transport level. &lt;span style=""&gt;    &lt;/span&gt;&lt;/p&gt;
&lt;table width="100%" cellspacing="0" cellpadding="0" border="1" style="width:100%;border-collapse:collapse;border:medium none;" class="MsoNormalTable"&gt;
&lt;tbody&gt;
&lt;tr style="height:15.75pt;"&gt;
&lt;td valign="top" style="border:1pt solid rgb(187, 187, 187);background:none repeat scroll 0% 0% rgb(229, 229, 229);padding:3pt;height:15.75pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;&lt;span style="font-size:10.5pt;color:black;"&gt;Binding &lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:1pt 1pt 1pt medium;border-style:solid solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% rgb(229, 229, 229);padding:3pt;height:15.75pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;&lt;span style="font-size:10.5pt;color:black;"&gt;Transport mode support   &lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:1pt 1pt 1pt medium;border-style:solid solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% rgb(229, 229, 229);padding:3pt;height:15.75pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;&lt;span style="font-size:10.5pt;color:black;"&gt;Message mode support &lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:1pt 1pt 1pt medium;border-style:solid solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% rgb(229, 229, 229);padding:3pt;height:15.75pt;"&gt;
&lt;p style="margin-bottom:0.0001pt;line-height:normal;" class="MsoNormal"&gt;&lt;span style="font-size:10.5pt;color:black;"&gt;TransportWithMessageCredential   support &lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt;border-style:none solid solid;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;strong&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;BasicHttpBinding&lt;/span&gt;&lt;/strong&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;Yes&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;Yes&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;Yes&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt;border-style:none solid solid;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;strong&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;WSHttpBinding&lt;/span&gt;&lt;/strong&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;Yes&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;Yes&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;Yes&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt;border-style:none solid solid;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;strong&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;WSDualHttpBinding&lt;/span&gt;&lt;/strong&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;No&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;Yes&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;No&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt;border-style:none solid solid;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;strong&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;NetTcpBinding&lt;/span&gt;&lt;/strong&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;Yes&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;Yes&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;Yes&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt;border-style:none solid solid;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;strong&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;NetNamedPipeBinding&lt;/span&gt;&lt;/strong&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;Yes&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;No&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;No&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt;border-style:none solid solid;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;strong&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;NetMsmqBinding&lt;/span&gt;&lt;/strong&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;Yes&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;Yes&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;No&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt;border-style:none solid solid;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;strong&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;MsmqIntegrationBinding&lt;/span&gt;&lt;/strong&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;Yes&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;No&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;No&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=""&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt;border-style:none solid solid;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;strong&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;wsFederationHttpBinding&lt;/span&gt;&lt;/strong&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;No&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;Yes&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" style="border-width:medium 1pt 1pt medium;border-style:none solid solid none;border-color:rgb(187, 187, 187) rgb(187, 187, 187);background:none repeat scroll 0% 0% white;padding:3pt;"&gt;
&lt;p style="margin-right:0.75pt;margin-left:0.75pt;line-height:140%;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;line-height:140%;color:black;"&gt;Yes&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p class="MsoNormal"&gt;From &lt;a rel="nofollow" target="_blank" href="http://msdn.microsoft.com/en-us/library/ms731172.aspx"&gt;http://msdn.microsoft.com/en-us/library/ms731172.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Up Next: Authentication&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;a rel="nofollow" target="_blank" href="http://msdn.microsoft.com/en-us/library/ms731172.aspx"&gt;&lt;br /&gt;
&lt;/a&gt;&lt;/p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;</encoded>
    </item>
    <item>
      <title>TFS 2010, VS2010 Database Projects, and CI</title>
      <link>http://www.opgenorth.net/2010/11/29/tfs-2010-vs2010-database-projects-and-ci/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=tfs-2010-vs2010-database-projects-and-ci</link>
      <description>I’m currently working on a project where there are some functional tests that require a SQL Server database. Before in the past I’ve always handled this by using Redgate’s excellent SQL Server tools to create a monolithic script that would deploy the DB Schema, and then another set of scripts to set up the data.&amp;#160; [...]</description>
      <guid>http://www.opgenorth.net/2010/11/29/tfs-2010-vs2010-database-projects-and-ci/</guid>
      <pubDate>Mon, 29 Nov 2010 21:19:00 +0000</pubDate>
      <encoded>&lt;p&gt;I’m currently working on a project where there are some functional tests that require a SQL Server database. Before in the past I’ve always handled this by using Redgate’s excellent SQL Server tools to create a monolithic script that would deploy the DB Schema, and then another set of scripts to set up the data.&amp;#160; Then it’s pretty trivial to use OSQL.EXE to run the scripts and setup the database.&lt;/p&gt;
&lt;p&gt;However, in this case, I’m constrained to use the VS2010 database project and TFS Build.&amp;#160; So, the trick for me became how to use TFS 2010 Team Build to deploy a fresh copy of the database before the functional tests are run.&amp;#160; After a bit of jiggery-pokery, here is what I ended up doing.&amp;#160; I’m sure that at some point in my future, I will have to do this again, and nothing helps my failing memory like writing it down.&lt;/p&gt;
&lt;p&gt;First a rough overview:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Declare some variables to hold the physical path of my .dbproj and the default data path for SQL Server. &lt;/li&gt;
&lt;li&gt;Convert the source code control path of my .dbproj to the physical path on disk. &lt;/li&gt;
&lt;li&gt;To help with debugging and diagnostics, write a build message with the location of the physical path of the .dbproj &lt;/li&gt;
&lt;li&gt;Add an MSBuild task to my workflow that would deploy the .dbproj. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Without further adieu, here is more details breakdown of the steps involved.&lt;/p&gt;
&lt;h4&gt;Declare Variables&lt;/h4&gt;
&lt;p&gt;So, first things first – declare the two variables I need to hold the physical path to the .dbproj file, and the directory for my SQL Server databases.&amp;#160; This should be pretty simple and straight forward (assuming that the POS that is the “Workflow Designer” isn’t crashing VS2010 constantly).&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.opgenorth.net/wp-content/uploads/2010/11/image.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://www.opgenorth.net/wp-content/uploads/2010/11/image_thumb.png" width="1000" height="379"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Once that is out of the way I scrolled down the pretty, crashy, workflow designer until I came across the &lt;u&gt;Compile and Test&lt;/u&gt; sequence.&amp;#160; At the very start of it I added a sequence that I called &lt;u&gt;Deploy Database&lt;/u&gt;.&amp;#160; Inside this sequence I added the following Team Foundation Build Activities:&lt;/p&gt;
&lt;h4&gt;ConvertWorkspaceItem&lt;/h4&gt;
&lt;p&gt;The point to this BuildActivity is to figure where the hell on the file system TFS put one of the files.&amp;#160; Pretty straight forward:&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.opgenorth.net/wp-content/uploads/2010/11/image1.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://www.opgenorth.net/wp-content/uploads/2010/11/image_thumb1.png" width="691" height="192"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;WriteBuildMessage&lt;/h4&gt;
&lt;p&gt;Always nice to have a message in your log file to help with troubleshooting.&amp;#160; Here’s what my WriteBuildMessage activity looks like.&amp;#160; Notice that the message makes use of the “DbProjectPath” variable that we set above in the ConvertWorkspaceItemActivity.&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.opgenorth.net/wp-content/uploads/2010/11/image2.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://www.opgenorth.net/wp-content/uploads/2010/11/image_thumb2.png" width="687" height="146"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;MSBuild&lt;/h4&gt;
&lt;p&gt;This the working part of the the sequence.&amp;#160; In here we use MSBuild to call the .dbproj and deploy a fresh copy of the database to SQL Server. Key properties to set:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CommandLineArguments : this contains the properties to pass on the command line when deploying.&amp;#160; You’ll want to provide these properties
&lt;ul&gt;
&lt;li&gt;/p:TargetDatabase=YOUR_DATABASE_NAME &lt;/li&gt;
&lt;li&gt;/p:”DefaultDataPath=DIRECTORY_OF_DATABASE_FILES” &lt;/li&gt;
&lt;li&gt;/p:”TargetConnectionString=YOUR_CONNECTION_STRING_FOR_THE_TARGET_DATABASE” &lt;/li&gt;
&lt;li&gt;/p:DeployToDatabase=True &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Configuration : just specify which configuration in the solution to use. &lt;/li&gt;
&lt;li&gt;DisplayName : what ever you want, this is how the MSBuild activity will be displayed in your sequence &lt;/li&gt;
&lt;li&gt;LogFile : the name of the log file for the deploy &lt;/li&gt;
&lt;li&gt;OutDir : the output directory &lt;/li&gt;
&lt;li&gt;Project : Notice that this is the value of DbProjectPath, which we set above in our ConvertWorkItem &lt;/li&gt;
&lt;li&gt;RunCodeAnalysis : Set this to CodeAnalysisOption.Never.&amp;#160; Doesn’t make much sense to do code analysis on a database project. &lt;/li&gt;
&lt;li&gt;Targets : &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is what the properties look like for this particuar Build Activity:&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.opgenorth.net/wp-content/uploads/2010/11/image3.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://www.opgenorth.net/wp-content/uploads/2010/11/image_thumb3.png" width="648" height="493"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now all of this has to live somewhere.&amp;#160; You might want to have this live somewhere else depending on when or how you want the database to deploy.&amp;#160; In my case, as I wanted to deploy the database BEFORE my tests ran, I hunted through the workflow and found the sequence called &lt;u&gt;Run Tests&lt;/u&gt;.&amp;#160; I modified one side of the If condition to include a new sequence call &lt;u&gt;Deploy DB and Run Tests&lt;/u&gt;:&lt;a rel="nofollow" target="_blank" href="http://www.opgenorth.net/wp-content/uploads/2010/11/image4.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://www.opgenorth.net/wp-content/uploads/2010/11/image_thumb4.png" width="501" height="349"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here is an overview of what my Deploy DB and Run Tests sequence looks like&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.opgenorth.net/wp-content/uploads/2010/11/image5.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://www.opgenorth.net/wp-content/uploads/2010/11/image_thumb5.png" width="257" height="502"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;#160;&lt;/p&gt;
&lt;h4&gt;After Thoughts&lt;/h4&gt;
&lt;p&gt;To be honest, I found the whole process annoying and awkward.&amp;#160; Sure, I didn’t have to edit a bunch of XML by hand, but the Workflow Designer in Visual Studio 2010 wasn’t exactly a joy to work with either.&amp;#160; I don’t know exactly what the problem was, but it kept crashing while I was trying to edit this Build Process Template. It was always the same error, an Out of Memory Exception.&amp;#160; On a Dell Latitude E6510 with 4GB of memory, this shouldn’t be happening.&amp;#160; As well, the whole editing process for the work flow was awkward at best.&lt;/p&gt;
&lt;p&gt;As much as I dislike XML based build tools, at least text editors don’t get all crashy and such.&amp;#160; As well, I found the overall experience of trying to create and piece together the workflow for Team Build to be sluggish and tedious.&amp;#160; It’s great to have a GUI editor to hide the crummy XML, but honestly, I think the way &lt;a rel="nofollow" target="_blank" href="http://www.finalbuilder.com/home.aspx"&gt;FinalBuilder&lt;/a&gt; works is far superior to how VS2010 in terms of easy of use and readability(application crashes aside).&lt;/p&gt;
&lt;p&gt;Next is to setup my Release build definition, and to tackle the issue of updated the version number in AssemblyInfo.cs and creating a zip file of all the deployment artifacts.&amp;#160; But first I’ve got to go and buy a bottle or two of Talisker to help numb the pain that will follow as I go done down that path.&lt;/p&gt;</encoded>
    </item>
    <item>
      <title>First Impressions: Windows Phone 7 Development</title>
      <link>http://www.opgenorth.net/2010/11/15/first-impressions-windows-phone-7-development/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=first-impressions-windows-phone-7-development</link>
      <description>I’ve spent a bit of my spare time in the past week looking at Windows Phone 7 from a developer’s point of view.  I’d have started sooner, but honestly, I didn’t see the point until there were actually devices that I could hold and use.  I know that in the U.S., some guys got developer [...]</description>
      <guid>http://www.opgenorth.net/2010/11/15/first-impressions-windows-phone-7-development/</guid>
      <pubDate>Tue, 16 Nov 2010 04:01:55 +0000</pubDate>
      <encoded>&lt;p&gt;I’ve spent a bit of my spare time in the past week looking at Windows Phone 7 from a developer’s point of view.  I’d have started sooner, but honestly, I didn’t see the point until there were actually devices that I could hold and use.  I know that in the U.S., some guys got developer phones from Microsoft, but I don’t think that anybody up here in Canada was that lucky.&lt;/p&gt;
&lt;p&gt;So, over the past year or so I’ve been dabbling with Android and I actually like programming for Android.  The biggest issues I’ve run into with Android are my lack of Java skills – I keep doing things the C# way (you really don’t realize how handy Linq is until you don’t have it) and the fact that Android doesn’t have a decent UI designer.  But otherwise, I like Android.&lt;/p&gt;
&lt;p&gt;So, I was curious what the developer experience was for WP7.  In a nutshell – it’s not bad, and in some ways better than that of Android.&lt;/p&gt;
&lt;p&gt;Things I like about WP7 development:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Being a C# guy, it was pretty easy and fast for me to get going with WP7.  Of course, Novell now has &lt;a rel="nofollow" target="_blank" href="http://www.monodroid.net"&gt;MonoDroid&lt;/a&gt; which in theory should lessen the learning curve for a C# guy to create Android applications.&lt;/li&gt;
&lt;li&gt;It’s nice to have good tooling to help with creating my UI’s.  Blend and Cider are pretty decent. Android does have &lt;a rel="nofollow" target="_blank" href="http://droiddraw.org"&gt;DroidDraw&lt;/a&gt;, but I’ve never really found that tool to be good to work with.  Eclipse has some sort of an GUI designer thingy, but again, I’ve found it to be kind of lack-lustre at best.  That, and I don’t use Eclipse – I prefer IntelliJ.&lt;/li&gt;
&lt;li&gt;The Emulator seems to start up faster to me that the Android emulator – but that could just be me.&lt;/li&gt;
&lt;li&gt;The MVVM pattern.  I know the theory, and am now learning the more practical side of it.  Was worried that WP7 was going to decent into the path of darkness and pain that was/is Web Forms.&lt;/li&gt;
&lt;li&gt;I think that the debugger integrates better with the WP7 emulator.  Not that, generally speaking, I spend a lot of time in the debugger, but when you need it, it does seem to be more natural to me.  Again, this could just be because by day I do a lot of C# development so I’m more used to the Microsoft tooling to begin with.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some things I didn’t like about WP7 development:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You have to have Vista or Windows 7.  Yes, I know, XP is almost 10 years old, time to move on.  Call me an O/S curmudgeon.  I don’t mind Windows 7, but Vista sucks/sucked.&lt;/li&gt;
&lt;li&gt;It seems like to build your apps, you have to use Visual Studio 2010.  Not a problem for a developer, but I’m old school when it comes to compiling applications, and your build server shouldn’t be tainted by your IDE.&lt;/li&gt;
&lt;li&gt;I’m use to the relatively easy going Google marketplace and the fact I have numerous avenues available to me to distribute Android applications.  No such joy with WP7 apps.&lt;/li&gt;
&lt;li&gt;Editing XAML by hand.  But, I suppose it’s no worse that the XML resource files that Android uses.&lt;/li&gt;
&lt;li&gt;Not seeing a lot of projects whose code I can read.  Granted it’s still early, so hopefully that will change.  Or not.  .NET doesn’t seem to have the same OSS community spirit that Java does.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Microsoft has always tried to be pretty good to developers (sometimes to their own detriment), but I think Windows Phone 7 does have some things going for it, from a developer’s point of view anyway.  Here’s to hoping that strategy pays off – that cool apps will get written for WP7, and that it will be commercially viable.  Competition is good – it will keep Apple and Google on their toes.  &lt;img class="wlEmoticon wlEmoticon-smile" style="border-style:none;" src="http://www.opgenorth.net/wp-content/uploads/2010/11/wlEmoticon-smile.png" alt="Smile"/&gt;&lt;/p&gt;</encoded>
    </item>
    <item>
      <title>Much Ado About Agile 2010 &amp;ndash; Aspect Oriented Programming materials</title>
      <link>http://feedproxy.google.com/~r/igloocoder/~3/Vav9lzeuyqk/much-ado-about-agile-2010-ndash-aspect-oriented-programming-materials.aspx</link>
      <description>&lt;p&gt;As promised here is the &lt;a rel="nofollow" target="_blank" href="http://www.igloocoder.com/presentations/agilevancouver/aop_slidedeck.zip"&gt;slide deck&lt;/a&gt; and the &lt;a rel="nofollow" target="_blank" href="http://www.igloocoder.com/presentations/agilevancouver/aop_source.zip"&gt;completed code&lt;/a&gt; materials that were covered in my session at &lt;a rel="nofollow" target="_blank" href="http://www.agilevancouver.ca"&gt;Agile Vancouver&lt;/a&gt;.  I had a great time interacting with the attendees in the session and throughout the rest of the conference.  Kudos to the organizers of Agile Vancouver for having created such a fantastic event.&lt;/p&gt;&lt;img src="http://igloocoder.com/aggbug/1458.aspx" width="1" height="1"/&gt;</description>
      <guid>http://igloocoder.com/archive/2010/11/03/much-ado-about-agile-2010-ndash-aspect-oriented-programming-materials.aspx</guid>
      <pubDate>Wed, 03 Nov 2010 19:14:46 +0000</pubDate>
      <category>Sessions</category>
    </item>
    <item>
      <title>YEG Open Data, the 2010 Edmonton Municipal Election, and Android</title>
      <link>http://www.opgenorth.net/2010/10/15/yeg-open-data-the-2010-edmonton-municipal-election-and-android/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=yeg-open-data-the-2010-edmonton-municipal-election-and-android</link>
      <description>(Or, things to do when you have a sick kid) One of the new data catalogues that the City of Edmonton has put up is the 2010 Election Results.&amp;#160; This Thanksgiving Long Weekend I was kind of “grounded” at home when my son came down with a nasty inner ear infection.&amp;#160; I was hanging out [...]</description>
      <guid>http://www.opgenorth.net/?p=306</guid>
      <pubDate>Fri, 15 Oct 2010 13:55:00 +0000</pubDate>
      <encoded>&lt;p&gt;&lt;em&gt;(Or, things to do when you have a sick kid)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;margin-left:0px;border-left-width:0px;margin-right:0px;" title="election" border="0" alt="election" align="right" src="http://www.opgenorth.net/wp-content/uploads/2010/10/election.jpg" width="126" height="162"/&gt;&lt;/p&gt;
&lt;p&gt;One of the new &lt;a rel="nofollow" target="_blank" href="http://data.edmonton.ca/"&gt;data catalogues&lt;/a&gt; that the City of Edmonton has put up is the &lt;a rel="nofollow" target="_blank" href="http://data.edmonton.ca/DataBrowser/coe/Election2010Results#param=NOFILTER--DataView--Results"&gt;2010 Election Results&lt;/a&gt;.&amp;#160; This Thanksgiving Long Weekend I was kind of “grounded” at home when my son came down with a nasty inner ear infection.&amp;#160; I was hanging out with him, and thought I could use the time to see how hard it would be and how quickly I could put together an Android application that would poll these results and show leading candidate in each contest for a given ward.&amp;#160; Turns out it was not that hard at all.&amp;#160; Development time was less than one day, and then I had the application running on my phone for a couple of days.&lt;/p&gt;
&lt;p&gt;If you search the Android market place for YEG Vote, and you’re running Android 1.6 or higher you should able to find the application and install it (assuming, of course, you care about the election results).&amp;#160; The application itself is pretty bare bones.&amp;#160; It will get the results every five minutes, and then show the leading candidate.&lt;/p&gt;
&lt;p&gt;I think my next trick will be to duplicate the application in C# and &lt;a rel="nofollow" target="_blank" href="http://monodroid.net/"&gt;MonoDroid&lt;/a&gt; just to get a feel for the differences and such.&amp;#160; I’d wager that it will take even less time in &lt;a rel="nofollow" target="_blank" href="http://monodroid.net/"&gt;MonoDroid&lt;/a&gt; for me, given that I’m much more fluent in C# than I am in Java.&amp;#160; I’d have done this in &lt;a rel="nofollow" target="_blank" href="http://monodroid.net/"&gt;MonoDroid&lt;/a&gt; to being with, but &lt;a rel="nofollow" target="_blank" href="http://monodroid.net/"&gt;MonoDroid&lt;/a&gt; is currently in a limited preview and one of the conditions of being in the preview program is that you can’t distribute applications written in &lt;a rel="nofollow" target="_blank" href="http://monodroid.net/"&gt;MonoDroid&lt;/a&gt; yet. I would have tried a Windows Phone 7 port, but it just doesn’t make much sense, given that the number of people in Alberta with actually WP7 devices is probably less than 10.&amp;#160; Maybe next election.&lt;/p&gt;
&lt;p&gt;If you have any suggestions or ideas, feel free to let me know. If I can scrounge up some time this weekend before the election I’ll see if I can implement them.&lt;/p&gt;
&lt;p&gt;And, it goes without saying, regardless of what you think about this application,&lt;strong&gt; if you live in Alberta, make sure you get out and vote this Monday (October 18th, 2010).&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" title="screenshot1" border="0" alt="screenshot1" src="http://www.opgenorth.net/wp-content/uploads/2010/10/screenshot1.png" width="234" height="349"/&gt;&lt;/p&gt;</encoded>
    </item>
    <item>
      <title>UI Workflow is business logic</title>
      <link>http://feedproxy.google.com/~r/igloocoder/~3/D85-31GTUNk/ui-workflow-is-business-logic.aspx</link>
      <description>&lt;p&gt;Over my years as a programmer I’ve focussed a lot of attention and energy on business logic.  I’m sure you have too.  Business logic is, after all, a huge part of what our clients/end users want to see as an output from our development efforts.  But what is included in business logic?  Usually we think of all the conditionals, looping, data mangle-ment, reporting and other similar things.  In my past experiences I’ve poured immense effort into ensuring that this business logic was correct (automated and manual testing), documented (ubiquitous language, automated testing and, yes, comments when appropriate) and centralized (DDD).  While I’ve had intense focus on these needs and practices, I’ve usually neglected to recognize the business logic that is buried in the UI workflow within the application.&lt;/p&gt;  &lt;p&gt;On my current project I’ve been presented with an opportunity to explore this area a bit more in depth.  We don’t have the volume of what I have traditionally considered business logic.  Instead the application is very UI intensive.  As a result I’ve been spending a lot more time worrying about things like “What happens when the user clicks XYZ?”  It became obvious to us very early on that this was the heart of our application’s business logic.&lt;/p&gt;  &lt;p&gt;Once I realized this we were able to focus our attention on the correctness, discoverability, centralization and documentation of the UI workflow.  How did we accomplish this then?  I remember reading somewhere (written by Jeremy Miller I think, although I can’t find a link now) the assertion that “Every application will require the command pattern at some point.” I did some research and found a &lt;a rel="nofollow" target="_blank" href="http://www.lostechies.com/blogs/derickbailey/archive/2009/12/22/understanding-the-application-controller-through-object-messaging-patterns.aspx"&gt;post by Derick Bailey&lt;/a&gt; explaining how he was using an Application Controller to handle both an Event Aggregator and workflow services.  To quote him:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Workflow services are the 1,000 foot view of how things get done. They are the direct modeling of a flowchart diagram in code.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I focused on the first part of his assertion and applied it to the flow of user interfaces.  Basically it has amounted to each user workflow (or sequence of UI concepts) being defined, and executed, in one location.  As an example we have a CreateNewCustomerWorkflowCommand that is executed when the user clicks on the File | Create Customer menu.  It might look something like this:&lt;/p&gt;  &lt;p /&gt;  &lt;div style="width:850px;color:black;overflow:auto;"&gt;   &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#2b91af;"&gt;CreateNewCustomerWorkflowCommand&lt;/span&gt;&lt;span style="color:#000000;"&gt;  : &lt;span style="color:#2b91af;"&gt;ICommand&lt;/span&gt;&lt;span style="color:#000000;"&gt; &amp;lt;&lt;span style="color:#2b91af;"&gt;CreateNewCustomerWorkflow&lt;/span&gt;&lt;span style="color:#000000;"&gt; &amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;2:&lt;/span&gt; &lt;span style="color:#000000;"&gt;{&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#2b91af;"&gt;ISaveChangesPresenter&lt;/span&gt;&lt;span style="color:#000000;"&gt;  _saveChangesPresenter;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;4:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#2b91af;"&gt;ICustomerService&lt;/span&gt;&lt;span style="color:#000000;"&gt;  _customerService;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;5:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#2b91af;"&gt;ICreateNewCustomerPresenter&lt;/span&gt;&lt;span style="color:#000000;"&gt;  _createNewCustomerPresenter;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;6:&lt;/span&gt; &lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;7:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt;  CreateNewCustomerWorkflowCommand(&lt;span style="color:#2b91af;"&gt;ISaveChangesPresenter&lt;/span&gt;&lt;span style="color:#000000;"&gt;  saveChangesPresenter,&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;8:&lt;/span&gt;                                             &lt;span style="color:#2b91af;"&gt;ICustomerService&lt;/span&gt;&lt;span style="color:#000000;"&gt;  customerService,&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;9:&lt;/span&gt;                                             &lt;span style="color:#2b91af;"&gt;ICreateNewCustomerPresenter&lt;/span&gt;&lt;span style="color:#000000;"&gt;  createNewCustomerPresenter)&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;10:&lt;/span&gt;     &lt;span style="color:#000000;"&gt;{&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;11:&lt;/span&gt;         _saveChangesPresenter = saveChangesPresenter;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;12:&lt;/span&gt;         _customerService = customerService;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;13:&lt;/span&gt;         _createNewCustomerPresenter = createNewCustomerPresenter;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;14:&lt;/span&gt;     &lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;15:&lt;/span&gt; &lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;16:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt;  Execute(&lt;span style="color:#2b91af;"&gt;CreateNewCustomerWorkflow&lt;/span&gt;&lt;span style="color:#000000;"&gt;  commandParameter)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;17:&lt;/span&gt;     &lt;span style="color:#000000;"&gt;{&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;18:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt;  (commandParameter.CurrentScreenIsDirty)&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;19:&lt;/span&gt;         &lt;span style="color:#000000;"&gt;{&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;20:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt;&lt;span style="color:#000000;"&gt;  saveChangesResults = _saveChangesPresenter.Run();&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;21:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt;  (saveChangesResults.ResultState == &lt;span style="color:#2b91af;"&gt;ResultState&lt;/span&gt;&lt;span style="color:#000000;"&gt; .Cancelled) &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; ;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;22:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt;  (saveChangesResults.ResultState == &lt;span style="color:#2b91af;"&gt;ResultState&lt;/span&gt;&lt;span style="color:#000000;"&gt; .Yes)&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;23:&lt;/span&gt;             &lt;span style="color:#000000;"&gt;{&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;24:&lt;/span&gt;                 _customerService.Save(commandParameter.CurrentScreenCustomerSaveDto);&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;25:&lt;/span&gt;             &lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;26:&lt;/span&gt;         &lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;27:&lt;/span&gt; &lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;28:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt;&lt;span style="color:#000000;"&gt;  newCustomerResults = _createNewCustomerPresenter.Run();&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;29:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt;  (newCustomerResults.ResultState == &lt;span style="color:#2b91af;"&gt;ResultState&lt;/span&gt;&lt;span style="color:#000000;"&gt; .Cancelled) &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; ;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;30:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt;  (newCustomerResults.ResultState == &lt;span style="color:#2b91af;"&gt;ResultState&lt;/span&gt;&lt;span style="color:#000000;"&gt; .Save)&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;31:&lt;/span&gt;         &lt;span style="color:#000000;"&gt;{&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;32:&lt;/span&gt;             _customerService.Save(newCustomerResults.Data);&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;33:&lt;/span&gt;         &lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;34:&lt;/span&gt;     &lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;35:&lt;/span&gt; &lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p /&gt;

&lt;p&gt;As you can see the high level design of the user interaction, and service interaction, is clearly defined here.  Make no mistake, this is business logic.  It answers the question of how does the business expect the creation of a new customer to occur.  We’ve clearly defined this situation in one encapsulated piece of code.  By doing this we have now laid out a pattern whereby any developer looking for a business action can look through these workflows.  They clearly document the expected behaviour during the situation.  Since we’re using Dependency Injection in our situation, we can also write clear tests to continuously validate these expected behaviours.  Those tests, when done in specific ways, can also enhance the documentation surrounding the system.  For example, using BDD style naming and a small utility to retrieve and format the TestFixture and Test names we can generate something like the following:&lt;/p&gt;

&lt;p /&gt;

&lt;div style="width:850px;color:black;overflow:auto;"&gt;
  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#2b91af;"&gt;When_the_current_screen_has_pending_changes&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;2:&lt;/span&gt; &lt;span style="color:#000000;"&gt; &lt;span style="color:#000000;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt;  the_user_should_be_prompted_with_the_option_to_save_those_changes()&lt;span style="color:#000000;"&gt;{&lt;/span&gt;&lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;4:&lt;/span&gt; &lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;5:&lt;/span&gt; &lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;6:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#2b91af;"&gt;When_the_user_chooses_to_cancel_when_asked_to_save_pending_changes&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;7:&lt;/span&gt; &lt;span style="color:#000000;"&gt; &lt;span style="color:#000000;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;8:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt;  the_pending_changes_should_not_be_saved()&lt;span style="color:#000000;"&gt;{&lt;/span&gt;&lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;9:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt;  the_create_new_customer_dialog_should_not_be_displayed()&lt;span style="color:#000000;"&gt;{&lt;/span&gt;&lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;10:&lt;/span&gt; &lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;11:&lt;/span&gt; &lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;12:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#2b91af;"&gt;When_the_user_chooses_not_to_save_pending_changes&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;13:&lt;/span&gt; &lt;span style="color:#000000;"&gt; &lt;span style="color:#000000;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;14:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt;  the_pending_changes_should_not_be_saved()&lt;span style="color:#000000;"&gt;{&lt;/span&gt;&lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;15:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt;  the_create_new_customer_dialog_should_be_displayed()&lt;span style="color:#000000;"&gt;{&lt;/span&gt;&lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;16:&lt;/span&gt; &lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;17:&lt;/span&gt; &lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;18:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#2b91af;"&gt;When_the_user_chooses_to_to_save_pending_changes&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;19:&lt;/span&gt; &lt;span style="color:#000000;"&gt; &lt;span style="color:#000000;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;20:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt;  the_pending_changes_should_be_saved()&lt;span style="color:#000000;"&gt;{&lt;/span&gt;&lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;21:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt;  the_create_new_customer_dialog_should_be_displayed()&lt;span style="color:#000000;"&gt;{&lt;/span&gt;&lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;22:&lt;/span&gt; &lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;23:&lt;/span&gt; &lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;24:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#2b91af;"&gt;When_the_user_chooses_to_cancel_from_creating_a_new_customer&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;25:&lt;/span&gt; &lt;span style="color:#000000;"&gt; &lt;span style="color:#000000;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;26:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt;  the_new_customer_should_not_be_saved()&lt;span style="color:#000000;"&gt;{&lt;/span&gt;&lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;27:&lt;/span&gt; &lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;28:&lt;/span&gt; &lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;29:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#2b91af;"&gt;When_the_user_chooses_to_create_a_new_customer&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;30:&lt;/span&gt; &lt;span style="color:#000000;"&gt; &lt;span style="color:#000000;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;background:#f4f4f4;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;31:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt;  &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt;  the_new_customer_should_be_saved()&lt;span style="color:#000000;"&gt;{&lt;/span&gt;&lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0em;"&gt;&lt;span style="text-align:right;width:30px;display:inline-block;color:black;margin-right:10px;"&gt;32:&lt;/span&gt; &lt;span style="color:#000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p /&gt;

&lt;p&gt;As you can see, this technique allows us to create a rich set of documentation outlining how the application should interact with the user when they are creating a new customer.&lt;/p&gt;

&lt;p&gt;Now that we’ve finished implementing this pattern a few times, have I seen any drawbacks?  Not really.  If we didn’t use this technique we’d still have to write the code to coordinate the screen sequencing.  That sequencing would be spread all over the codebase, most likely in the event handlers for buttons on forms (or their associated Presenter/Controller code).  Instead we’ve introduced a couple more classes per workflow and have centralized the sequencing in them.  So the trade off was the addition of a couple of classes per workflow for more discoverability, testability and documentation.  A no brainer if you ask me.&lt;/p&gt;

&lt;p&gt;Is this solution the panacea?  Absolutely not.  It works very well for the application that we’re building though.  In the future will I consider using this pattern? Without doubt.  It might morph and change a bit based on the next application’s needs, but I think that the basic idea is strong and has significant benefits.&lt;/p&gt;

&lt;p&gt;A big shout out to Derick Bailey for writing a great post on the &lt;a rel="nofollow" target="_blank" href="http://www.lostechies.com/blogs/derickbailey/archive/2009/12/22/understanding-the-application-controller-through-object-messaging-patterns.aspx"&gt;Application Controller, Event Aggregator and Workflow Services&lt;/a&gt;.  Derick even has a sample app available for reference.  I found it to be great for getting started, but it is a little bit trivial as it only implements one simple workflow.  Equally big kudos to Jeremy Miller and his &lt;a rel="nofollow" target="_blank" href="http://codebetter.com/blogs/jeremy.miller/archive/2007/07/25/the-build-your-own-cab-series-table-of-contents.aspx"&gt;Build Your Own CAB&lt;/a&gt; series which touches all around this type of concept.  Reading both of these sources helped to cement that there was a better way.&lt;/p&gt;&lt;img src="http://igloocoder.com/aggbug/1457.aspx" width="1" height="1"/&gt;</description>
      <guid>http://igloocoder.com/archive/2010/09/26/ui-workflow-is-business-logic.aspx</guid>
      <pubDate>Sun, 26 Sep 2010 23:42:00 +0000</pubDate>
    </item>
    <item>
      <title>Looking for a Job?</title>
      <link>http://www.opgenorth.net/2010/09/21/looking-for-a-job/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=looking-for-a-job</link>
      <description>If you happen to be a .NET type, knowledgeable/interested in MVC and Agile, QuestionMark is looking for .NET developers (F/T only, no contractors) here in Edmonton, Alberta.&amp;#160; Below is the job description.&amp;#160; If you’re interested, send your resume to Kaitlyn Lardin at QuestionMark (kaitlyn AT questionmark DOT com): &amp;#160; Senior Software Developer Background Questionmark is [...]</description>
      <guid>http://www.opgenorth.net/2010/09/21/looking-for-a-job/</guid>
      <pubDate>Tue, 21 Sep 2010 15:15:32 +0000</pubDate>
      <encoded>&lt;p&gt;If you happen to be a .NET type, knowledgeable/interested in MVC and Agile, QuestionMark is looking for .NET developers (F/T only, no contractors) here in Edmonton, Alberta.&amp;#160; Below is the job description.&amp;#160; If you’re interested, send your resume to Kaitlyn Lardin at QuestionMark (kaitlyn AT questionmark DOT com):&lt;/p&gt;
&lt;p&gt;&amp;#160;&lt;/p&gt;
&lt;h3&gt;Senior Software Developer&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;Background&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Questionmark is a company with a 20 year history recognised global presence in e-learning and assessment automation with software covering all aspects of this field, from authoring to delivery and reporting. Our software is used by over 3 million people in 15 different countries throughout the world. Questionmark&lt;i&gt; &lt;/i&gt;is a fast-growing company, with a dedicated, passionate, and global workforce. We have offices in London, UK, Norwalk, CT and Tubize, Belgium. We care about the satisfaction of our employees and we reward them for meeting or exceeding expectations. The company promotes a relaxed, fun and highly productive approach to work. We have recently moved location to a vibrant office in the heart of downtown surrounded by software development companies.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Role of the Senior Developer&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;We are looking for a talented senior developer to join our development team in designing and creating the next generation of on-line assessment delivery software. This role will work closely with a Product Owner and other team members in a SCRUM environment, and be responsible for delivering potentially shippable functionality each Sprint. It also includes the mentoring of other team members through peer review. Our development team works in a Continuous Integration environment with automated builds and testing.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Essential skills:&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;· At least 5 years commercial experience development experience.&lt;/p&gt;
&lt;p&gt;· You will be highly skilled in software development using our core technologies of C#, ASP.NET, XML, JavaScript, SQL Server and/or Oracle.&lt;/p&gt;
&lt;p&gt;· Experience of jQuery very desirable &lt;/p&gt;
&lt;p&gt;· Experience of working with .NET 2.0 or later&lt;/p&gt;
&lt;p&gt;· Expertise in object oriented programming and relational databases&lt;/p&gt;
&lt;p&gt;· Expertise in T-SQL and/or PL/SQL&lt;/p&gt;
&lt;p&gt;· Good written and verbal communication. You must be able to write specifications&lt;/p&gt;
&lt;p&gt;· Experience working in a SCRUM environment is desirable &lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Attributes of the Senior Software Developer:&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The successful candidate will be highly skilled in software development using our core technologies, as above. You will be a self starting, self motivated individual who is enthusiastic and passionate about developing innovative software solutions.&lt;/p&gt;
&lt;p&gt;Candidates must be eligible to work within Canada and relocate to Edmonton. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;The package: &lt;/b&gt;&lt;/p&gt;
&lt;p&gt;We offer excellent salary and benefits that include flexible working hours, starting 14 days annual leave, company bonus scheme, generous health coverage, and subsidized gym membership. &lt;/p&gt;</encoded>
    </item>
    <item>
      <title>ASP.NET “POET” Vulnerability</title>
      <link>http://www.haveyougotwoods.ca/2010/09/20/asp-net-poet-vulnerability</link>
      <description>There has been lots of good posts so far about the ASP.NET vulnerability that was unveiled late Friday. In summary the attack exposes cryptographic keys used in ASP.net which can lead to all sorts of nastiness. I recommend you read and apply the advice from Scott Guthrie and then come back and read more. Microsoft [...]</description>
      <guid>http://haveyougotwoods.com/archive/2010/09/20/318.aspx</guid>
      <pubDate>Mon, 20 Sep 2010 18:51:48 +0000</pubDate>
      <encoded>&lt;p&gt;There has been lots of good posts so far about the ASP.NET vulnerability that was unveiled late Friday. In summary the attack exposes cryptographic keys used in ASP.net which can lead to all sorts of nastiness.&lt;/p&gt;
&lt;p&gt;I recommend you read and apply the advice from &lt;a rel="nofollow"&gt;Scott Guthrie&lt;/a&gt; and then come back and read more.&lt;/p&gt;
&lt;p&gt;Microsoft is releasing very little information on this issue until they have a fix ready. As such, some of the information here is based on my best guess of how it is actually working. Although these are assumptions the advice on how to avoid these attacks are not.&lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Components&lt;/span&gt;&lt;br /&gt;
What I have inferred from the given workaround is that there are two  components to this vulnerability. The first is an information disclosure vulnerability that certain responses to  requests give different error codes. The second is a side channel attack that occurs that reveals how long it took to yield a certain error code. &lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Information Disclosure Vulnerabilities&lt;/span&gt;&lt;br /&gt;
An information disclosure vulnerability is just what the name implies. Information is being disclosed that gives an attacker information. The classic example of this is with a login system that states &amp;#8220;Invalid Username&amp;#8221; when you use a username that does not exist and &amp;#8220;Invalid Password&amp;#8221; when you use a username that DOES exist but the wrong password. The system should just give you a generic error message and not reveal the reason for the login failure.&lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Side Channel Attacks&lt;/span&gt;&lt;br /&gt;
The attack is an example of a side channel attack. A side channel attack is when an attacker uses clues from a system to determine information instead of brute forcing the attack. The most common form of this is a timing attack in which an attacker looks at how long something takes to determine what is happening. Some other side channels that have been used have been looking at power consumption of systems, the sound the systems make, and the electromagnetic radiation given off by systems. Granted, timing attacks are the simplest to execute remotely (but network speed variability can introduce inaccurate timings.)&lt;/p&gt;
&lt;p&gt;A real world example of a timing attack would be my magic toaster. It has different settings for toast, bagels, waffles, and black pucks I can also tweak the darkness of the item with a dial. If I knew what time something was put into the toaster and what time it popped up I could probably determine the setting that was used on the toaster. With more refinement of my attack I could probably tell what the darkness toasting dial was set to as well. This attack is not precise though. Toast on 10 and Bagel on 1 might take the same amount of time (or close to it). Plus there may be differences in the materials inserted that affect timing (i.e. thin break or thick break). &lt;/p&gt;
&lt;p&gt;As you can see, side channel attacks do not (usually) net you what you are looking for with ease 100% of the time. The real thing they do is narrow down the possibilities of what could be happening. If I said guess a number between 1 and 1,000,000,000 it would take a while to get it. If I said guess a number between 1, and 1,000,000,000 but the number is 7, 34, or 2million&amp;#8230;. well that makes it a lot easier. &lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:bold;"&gt;The Workaround&lt;/span&gt;&lt;br /&gt;
As &lt;a rel="nofollow"&gt;descibed &lt;/a&gt;in Scott&amp;#8217;s post the workaround is two address these two issues. By having custom errors on (which you should have anyways) for all error codes to redirect to a page should address the information disclosure vulnerability. The page that Scott shows also puts in a random delay of the response to mitigate the timing side channel component.&lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:bold;"&gt;The Consequences&lt;/span&gt;&lt;br /&gt;
As this attack is used to determine encryption keys then I would state that encrypted data is at risk to being decryted. This would be things like viewstate, cookies, forms tickets, membership data, and more. As this attack is out there and should be fairly easy to automate I would consider my keys as most likely compromised. It appears the attack can run fairly quickly too (the example I saw got the key in 5 minutes).&lt;/p&gt;
&lt;p&gt;To this end it may be a good time to update keys (after you have applied the workaround) used in your systems. &lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Mitigating Information Disclosure In Your Code&lt;/span&gt;&lt;br /&gt;
Combating information disclosure of exceptions is fairly simple. In a client server environment I take any error the server throws and I log it (with as much information) and then return a generic error. In this case it may be that a 404 (page not found) error is returned in one case and 500 (internal server error) in another. Normally this is pretty standard behavior but it really does not help the user. In the end they wanted something and it did not happen so a generic error is sufficient. This can be achieved with the setting of a standard error page that hides the HTTP error code from the user. &lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Mitigating &lt;/span&gt;&lt;span style="font-weight:bold;"&gt;Timing Side Channel Attacks In Your Code&lt;/span&gt;&lt;br /&gt;
The timing side channel attack is tricky to spot as it is not a typical attack vector but it is fairly easy to fix. If you have code that can reveal information based on the time taken it may be practically to add a random wait time to responses. Going back to the login scenario it may take 2-5ms to determine if the user is in the database and then an additional 2-3ms to hash the password and compare it if the user exists. By seeing the process takes 2-5 ms before getting a login failure we see that the user probably did not exist. If it takes 7-10ms the user probably exists but the password was wrong. By adding a Thread.Sleep(cryptographically_random*) if the user is not found we can simulate the amount of time taken to hash and compare the password. &lt;/p&gt;
&lt;p&gt;But Wait! There&amp;#8217;s a catch. If we wait longer than the time it would take to hash the password we have just created the same problem. I.e. if we sleep for 0-20ms then an attacker may know that if it takes between 7-10ms that we have the right user and if it takes between 5-20ms is that the user was not found (but a sleep was added to lengthen the process). So adding wait time created the same issue we were trying to prevent! The most encompassing solution would be to wait on success or failure in this case. So no matter what the time it takes to execute something is variable. This may negatively affect performance though as you have threads sleeping all over. &lt;/p&gt;
&lt;p&gt;RANDOM IDEA AS I WRITE THIS POST: As every computer is different stating that success is a-b milliseconds and failure is x-y milliseconds as hardcoded fact in code does not work as the software may be installed in many different places (or upgraded to faster systems in the future). It may be an idea to build in a profiler around a sensitive method call that monitors the time it takes and then assures that subsequent calls fall within that range. &lt;/p&gt;
&lt;p&gt;*It is important not to just use Random as the sequence of Random can be  preditced. Using a crypto level random number generator generates a  more random random &lt;img src='http://www.haveyougotwoods.ca/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley'/&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Mitigating &lt;/span&gt;&lt;span style="font-weight:bold;"&gt;Timing Side Channel Attacks On Your Network Layer&lt;/span&gt;&lt;br /&gt;
The other component to this is that it takes multiple requests to the server to test different bits of data. The demo I saw did close to 40,000 requests. This may be able to be stopped or slowed down by rate limiting requests to a server to a reasonable/human level. It also leaves a pretty big log footprint on your servers.&lt;/p&gt;</encoded>
      <category>Security</category>
    </item>
    <item>
      <title>DateTime formatting for fr-CA</title>
      <link>http://feedproxy.google.com/~r/igloocoder/~3/6fCbX0TJ6VM/datetime-formatting-for-fr-ca.aspx</link>
      <description>&lt;p&gt;I just stumbled across a nice little hidden “feature” in the .NET framework.  If you’re running on a machine that has the CurrentCulture set to fr-CA the default DateTimeFormatInfo.CurrentInfo.ShortDatePattern is dd-MM-yyyy.  On my current project we wanted to allow the end user to override that value with their own format when a date is displayed on the screen.  The easy way to do this is to do something like DateTime.Now.ToString(“dd/MM/yyyy”).  Unfortunately the result from that will appear as 16-09-2010 still.  As far as I can tell (and there is very little backing this up), this is by design.  I’m not sure why at all.  If the CurrentCulture is set to en-CA both the formats of dd/MM/yyyy and dd-MM-yyyy will cause ToString() to output a value that you would expect, but as soon as you trip over to fr-CA the rules seem to change.&lt;/p&gt;  &lt;p&gt;If you’re running into this there is a relatively simple solution.  DateTime.Now.ToString(“dd&amp;#92;/MM&amp;#92;/yyyy”) will output 16/06/2010 as you’d expect.&lt;/p&gt;  &lt;p&gt;The more localization that I’m doing on this application, the more I’m finding nice hidden gems of inconsistency like this.&lt;/p&gt;&lt;img src="http://igloocoder.com/aggbug/1456.aspx" width="1" height="1"/&gt;</description>
      <guid>http://igloocoder.com/archive/2010/09/16/datetime-formatting-for-fr-ca.aspx</guid>
      <pubDate>Thu, 16 Sep 2010 17:33:41 +0000</pubDate>
    </item>
    <item>
      <title>Integration – Is It Worth It?</title>
      <link>http://www.haveyougotwoods.ca/2010/08/28/integration-is-it-worth-it</link>
      <description>One thing I get asked to do a lot is integrate systems with each other or incorporate other systems into one we are currently building. In a lot of scenarios I have been starting to give some pushback on this. Sure integration is cool and all but should it be done? Expense The first (and [...]</description>
      <guid>http://haveyougotwoods.com/archive/2010/08/28/317.aspx</guid>
      <pubDate>Sat, 28 Aug 2010 14:56:46 +0000</pubDate>
      <encoded>&lt;p&gt;One thing I get asked to do a lot is integrate systems with each other or incorporate other systems into one we are currently building. In a lot of scenarios I have been starting to give some pushback on this. Sure integration is cool and all but should it be done?&lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Expense&lt;/span&gt;&lt;br /&gt;
The first (and ongoing) issue is the expense of integrating systems. First you have to understand the systems (or at least the APIs being exposed) of each system which can take a lot of time. Secondly we have to write code to integrate the services and adapt concepts from one system to another. This work also needs to be tested and debugged. &lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Perpetuating The Legacy&lt;/span&gt;&lt;br /&gt;
The bigger issue I have seen in organizations is that tying a legacy system into your system makes it harder to change or replace the legacy system. If a legacy system has 3-4 systems that depend on it then any changes have to be tested and approved by the consuming systems (expense again). &lt;/p&gt;
&lt;p&gt;If we want to replace the legacy system with something better then we have two options. We can either rewrite the system and keep the old API exposed or we can throw it away and force our consumers to change. Rewriting a system and keeping the API may work IF the original API was perfect (or close to perfect). In practice I find that the API is ok but if a person were to rewrite it they could alleviate a lot of the issues and shortcomings discovered over the years. If we do a brand new interface then all our consumers need to change their code which can be&amp;#8230;. expensive.&lt;/p&gt;
&lt;p&gt;From being in this situation before I have compromised. I created a new system with a better API that was more expressive and simpler to use. I then created a separate project that exposed the old API and translated that to the new API. This does add some performance overhead in translation and lots of things to test (expensive).  It does allow new consumers to use a better API and allowed consumers of the old system to decide if it was worth migrating to the new API. &lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Integration For Integrations Sake&lt;/span&gt;&lt;br /&gt;
Many people automatically assume that if the information is in another system that we should integrate the two systems. This does help centralize rules, reduce duplication, and centralize information. This is all true but not always necessary. I would find it acceptable to have some minor duplication if it eliminated a coupling on another system. This is a very careful call to make though as this duplication can lead to duplication of maintainance. Even worse it can lead to their now being two sources of data so when a third system comes along it now consumes both sources for data to try and determine which one is accurate.&lt;/p&gt;
&lt;p&gt;One classic example I have is from a client of mine. They have a system that dispatches their vehicles and another system that uses GPS to track their vehicles. They asked for these systems to be integrated as they are always switching between the two. In this case the value of integrating the systems was very low. Instead I recommend that all their operators get two monitors and have both applications open. This is not the 100% perfect solution (unless you are an accountant) but it gets the job done for the right price.&lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Alternatives&lt;/span&gt;&lt;br /&gt;
There are ways to integrate but not integrate. One of the simpler ones is to have a button/link/menu item/whatever that fires up a system you would normally integrate with and pass along necessary data. I.e. a button that runs &amp;#8220;otherProgram.exe /RunSalesReport 10-10-2009 10-10-2010&amp;#8243; or http://server/SalesReport.aspx?start=10-10-2009&amp;amp;end=10-10-2010. Granted there is a bit of coupling there and some things to maintain but not as much as if we had to call a service, translate the results, and show it on a UI.&lt;/p&gt;
&lt;p&gt;Another method is to use manual entry. An example of this would be to use one system to find a product and then type that products manufacture code into your system you are building. Sure it is not as fast and the costs of this slowdown will add up over time but is the cost of integration still higher than the cost it takes for a user to copy/paste a code from one program to another? Not an easy question to answer but one that should be evaluated.&lt;/p&gt;
&lt;p&gt;The last method is one typically avoided: double entry. This is where the same (or similar) data is entered into two separate systems. An example of this might be for a sales operation. It may be acceptable for the sales system to have a list of all products, descriptions, and prices of products that they sell. The warehouse system might have its one list of products, dimensions, and inventory levels. As long as when a sale comes in that the order can be filled AND that the sales system does not need to know inventory levels when they make a sale (i.e. if there is none in the warehouse it will just get backordered). This is a very tight line to walk as if an item were entered into one system incorrectly the customer may order 20 Widgets but instead get 20 Gadgets due to the product codes not lining up.&lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Final Thoughts&lt;/span&gt;&lt;br /&gt;
I have learned that integration is more expensive than I first thought it would be. I thought that reducing code I had to write would make life easier. It does in some ways but in other ways it adds overhead to development and maintenance. If we just stop and think if it is really necessary to tie two systems together then we might just have a little less coupling and a little more freedom to upgrade some legacy systems. Not integrating is not the only solution&amp;#8230;. but neither is integrating. &lt;/p&gt;</encoded>
    </item>
    <item>
      <title>Learn From My Mistakes?</title>
      <link>http://www.haveyougotwoods.ca/2010/08/21/learn-from-my-mistakes</link>
      <description>One of my frustrations with Silverlight has been that the async model is rammed down your throat. I understand the reasoning that it is good to have the UI thread responsive while long running calls are happening. But to me that is something that I code and I control. The thing that gets me is [...]</description>
      <guid>http://haveyougotwoods.com/archive/2010/08/20/316.aspx</guid>
      <pubDate>Sat, 21 Aug 2010 01:06:05 +0000</pubDate>
      <encoded>&lt;p&gt;One of my frustrations with Silverlight has been that the async model is rammed down your throat. I understand the reasoning that it is good to have the UI thread responsive while long running calls are happening. But to me that is something that I code and I control. &lt;/p&gt;
&lt;p&gt;The thing that gets me is that there are times where several network operations may have to happen in sequence. Here is a simple contrived example:&lt;/p&gt;
&lt;p&gt;var service = new VehicleRentalService();&lt;br /&gt;
if (service.AreVehiclesAvailableToRent())&lt;br /&gt;
  {&lt;br /&gt;
  txtNumberOfCars.Text = service.GetNumberOfCarsForRent();&lt;br /&gt;
  if (service.IsTheFlakyOnlineRentalServiceRunning())&lt;br /&gt;
      {&lt;br /&gt;
       btnBookOnline.Enabled = true;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;/p&gt;
&lt;p&gt;Now for the above example I would run all this on 1 background thread (leaving the UI nice and responsive) and make sure that I properly delegate the control changes to the UI thread (as controls are not thread safe).&lt;/p&gt;
&lt;p&gt;Silverlight forces us to async the calls which leads to a lot of functions that chain together. I find this makes the code a lot harder to read and a lot harder to understand. Here is a hand written rewrite of the above example:&lt;/p&gt;
&lt;p&gt;public function Start()&lt;br /&gt;
{&lt;/p&gt;
&lt;div style="margin-left:40px;"&gt;var service = new VehicleRentalService();&lt;br /&gt;
service.AreVehiclesAvailableToRentCompleted+=VehiclesAvailableToRentResponseRecieved;&lt;br /&gt;
service.GetNumberOfCarsForRentCompleted+=NumberOfCarsForRentResponseRecieved;&lt;br /&gt;
service.IsTheFlakyOnlineRentalServiceRunningCompleted+=IsTheFlakyOnlineRentalServiceRunningResponseRecieved;
&lt;p&gt;service.AreVehiclesAvailableToRent();
&lt;/div&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;public function VehiclesAvailableToRentResponseRecieved(object sender, VehiclesAvailableToRentCompletedEventArgs e)&lt;br /&gt;
{&lt;br /&gt;
   if (e.Result)&lt;br /&gt;
      {&lt;br /&gt;
      service.GetNumberOfCarsForRent();&lt;br /&gt;
      service.IsTheFlakyOnlineRentalServiceRunning();&lt;br /&gt;
     }&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;public function NumberOfCarsForRentResponseRecieved(object sender, NumberOfCarsForRentCompletedEventArgs e)&lt;br /&gt;
{&lt;br /&gt;
    Dispatcher.BeginInvoke(delegate { txtNumberOfCars.Text = e.Result });&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;public function IsTheFlakyOnlineRentalServiceRunningResponseRecieved(object sender, IsTheFlakyOnlineRentalServiceRunningResponseRecievedCompletedEventArgs e)&lt;br /&gt;
{&lt;br /&gt;
    Dispatcher.BeginInvoke(delegate { btnBookOnline.Enabled = e.Result });&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;(Some may argue that there should be a GetSystemStatus method on the service that returns all this info to which I would probably agree. For the sake of this post though I am going to run with it).&lt;/p&gt;
&lt;p&gt;So the Silverlight code is longer, harder to read, and harder to maintain. It does have the benefit of getting the number of cars for rent and checking if the online booking system is running at the same time which is a nice plus. &lt;/p&gt;
&lt;p&gt;For an example a log more complicated than this one I was using a WebRequest to converse with a server in a very back and forth fashion and found that the code quickly became very hard to read so I set about to change things. My idea was to create a class that uses async calls in the background but appear to be synchronous by blocking the caller. i.e. &lt;/p&gt;
&lt;p&gt;string customerData = Request.GetResponse(&amp;#8220;http://www.dummy.com/getcustomer.aspx&amp;#8221;, &amp;#8220;CustomerId=1&amp;#8243;);&lt;br /&gt;
string customerAddress = Request.GetResponse(&amp;#8220;http://www.dummy.com/getaddress.aspx&amp;#8221;, ParseOutAddressId(customerData));&lt;/p&gt;
&lt;p&gt;PLEASE DO NOT USE THIS CODE AS IT DOES NOT WORK (hence the post title):&lt;/p&gt;
&lt;p&gt;    public class SyncRequestResponse&lt;br /&gt;
    {&lt;br /&gt;
        ManualResetEvent _requestCompleted;&lt;br /&gt;
        private WebRequest _request;&lt;br /&gt;
        private string _postData;&lt;br /&gt;
        private Uri _requestUrl;&lt;br /&gt;
        private static string _result;&lt;/p&gt;
&lt;p&gt;        public string GetResponse(Uri requestUrl, string postData)&lt;br /&gt;
        {&lt;br /&gt;
            _requestCompleted=new ManualResetEvent(false);&lt;br /&gt;
            _requestCompleted.Reset();&lt;br /&gt;
            _postData = postData;&lt;br /&gt;
            _requestUrl = requestUrl;&lt;br /&gt;
            StartRequest();&lt;br /&gt;
            _requestCompleted.WaitOne(1000); //block current thread until the response is received or the timeout is reached&lt;br /&gt;
            return _result; //the result should be filled now&lt;br /&gt;
        }&lt;/p&gt;
&lt;p&gt;        private void StartRequest()&lt;br /&gt;
        {&lt;br /&gt;
            _request = WebRequest.Create(_requestUrl);&lt;br /&gt;
            _request.ContentType = &amp;#8220;application/x-www-form-urlencoded&amp;#8221;;&lt;br /&gt;
            _request.Method = &amp;#8220;POST&amp;#8221;;&lt;br /&gt;
            _request.BeginGetRequestStream(GetRequestStreamCompleted, null);&lt;br /&gt;
        }&lt;/p&gt;
&lt;p&gt;        private void GetRequestStreamCompleted(IAsyncResult result)&lt;br /&gt;
        {&lt;br /&gt;
                //request stream has returned so fill it&lt;br /&gt;
                var content = Encoding.UTF8.GetBytes(_postData);&lt;br /&gt;
                var stream = _request.EndGetRequestStream(result );&lt;br /&gt;
                stream.Write(content, 0, content.Length);&lt;br /&gt;
                stream.Close();&lt;br /&gt;
                _request.BeginGetResponse(GetResponseFromRequest, null);&lt;br /&gt;
        }&lt;/p&gt;
&lt;p&gt;        private void GetResponseFromRequest(IAsyncResult ar)&lt;br /&gt;
        {&lt;br /&gt;
            var response = _request.EndGetResponse(ar);&lt;br /&gt;
            var sr = new StreamReader(response.GetResponseStream());&lt;br /&gt;
            _result = sr.ReadToEnd();&lt;br /&gt;
            _requestCompleted.Set();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;/p&gt;
&lt;p&gt;
What I quickly found was that the second my WaitOne() line ran was that the background methods would also hang. After a lot of mucking about and some research I found out one very important thing. The WebRequest and WebResponse methods call interacts with the browsers plugin API which runs on&amp;#8230;. the UI thread. So by blocking the UI thread it also blocks any calls to the plugin API which blocks my WebRequest methods.&lt;/p&gt;
&lt;p&gt;So to solve this I could probably place my sync wrapper onto a background thread to implement the back and forth conversations and then raise an event when it is done but after mucking around it just makes things too complex to read, follow, and maintain. It may still have its uses one day&amp;#8230; but it was not as clean as I would like&lt;/p&gt;
&lt;p&gt;Solution?&lt;br /&gt;
My main issue is when you have async methods that change so for WebRequest calls I decided to inline the callback methods it used. Again it is ugly but I find it simpler to follow a linear action:&lt;/p&gt;
&lt;p&gt;public string GetCustomerDataAndBindItToTextBox(Uri requestUrl, string postData)&lt;br /&gt;
            {&lt;br /&gt;
                var request = WebRequest.Create(requestUrl);&lt;br /&gt;
                request.ContentType = &amp;#8220;application/x-www-form-urlencoded&amp;#8221;;&lt;br /&gt;
                request.Method = &amp;#8220;POST&amp;#8221;;&lt;br /&gt;
                request.BeginGetRequestStream(delegate(IAsyncResult result)&lt;br /&gt;
                                                   {&lt;br /&gt;
                                                       byte[] content = Encoding.UTF8.GetBytes(postData);&lt;br /&gt;
                                                       Stream stream = request.EndGetRequestStream(result);&lt;br /&gt;
                                                       stream.Write(content, 0, content.Length);&lt;br /&gt;
                                                       stream.Close();&lt;br /&gt;
                                                       request.BeginGetResponse(delegate (IAsyncResult result2)&lt;br /&gt;
                                                                                     {&lt;br /&gt;
                                                                                         WebResponse response = request.EndGetResponse(result2);&lt;br /&gt;
                                                                                         var sr = new StreamReader(response.GetResponseStream());&lt;br /&gt;
                                                                                         this.txtCustomer.Text = sr.ReadToEnd();&lt;br /&gt;
                                                                                     }, null);&lt;br /&gt;
                                                   }, null);&lt;/p&gt;
&lt;p&gt;
            }&lt;/p&gt;</encoded>
      <category>General</category>
    </item>
    <item>
      <title>MVVM and Designer Data</title>
      <link>http://www.haveyougotwoods.ca/2010/08/19/mvvm-and-designer-data</link>
      <description>Over the last week I have been playing around with Silverlight and the Model View View Model (MVVM) pattern that I have heard such great things about. So far it is a really nice way to separate the UI logic from the UI and make it easily testable. One of the things I loved in [...]</description>
      <guid>http://haveyougotwoods.com/archive/2010/08/19/315.aspx</guid>
      <pubDate>Thu, 19 Aug 2010 16:15:12 +0000</pubDate>
      <encoded>&lt;p&gt;Over the last week I have been playing around with Silverlight and the Model View View Model (MVVM) pattern that I have heard such great things about. So far it is a really nice way to separate the UI logic from the UI and make it easily testable. &lt;/p&gt;
&lt;p&gt;One of the things I loved in Silverlight was the support for design time data. Design time data allowed you to specify dummy data that would appear in VS/Blend so that you could work with the UI with sample data. This saves so much time as now you don&amp;#8217;t have to open the app, (possibly login), navigate to the area you are working on, and then see if you have it the way you want.&lt;/p&gt;
&lt;p&gt;The challenge was now to combine MVVM and this dummy design time data. It is a lot simpler than I thought. I simply created a dummy View Model that inherited from my runtime VM and loaded it with sample data.&lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Runtime ViewModel:&lt;/span&gt;&lt;br /&gt;
public class SummaryViewModel : BaseViewModel&lt;br /&gt;
    {&lt;br /&gt;
        public int MoviesOwned { get; set; }&lt;br /&gt;
        public int MoviesCurrentlyRentedOut { get; set; }&lt;br /&gt;
        public ObservableCollection&amp;lt;Category&amp;gt; Categories { get; set; }&lt;/p&gt;
&lt;p&gt;        private readonly MovieServiceClient _service; &lt;br /&gt;
        public SummaryViewModel()&lt;br /&gt;
        {&lt;br /&gt;
            _service = new MovieServiceClient();&lt;br /&gt;
            _service.GetAllCategoriesCompleted += GetAllCategoriesCompleted;&lt;br /&gt;
            if (!System.ComponentModel.DesignerProperties.IsInDesignTool)             &lt;br /&gt;
                _service.GetAllCategoriesAsync();&lt;br /&gt;
        }&lt;/p&gt;
&lt;p&gt;        private void GetAllCategoriesCompleted(object sender, GetAllCategoriesCompletedEventArgs e)&lt;br /&gt;
        {&lt;br /&gt;
            Categories = e.Result;&lt;br /&gt;
            InvokePropertyChanged(&amp;#8220;Categories&amp;#8221;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Design Time View Model:&lt;/span&gt;&lt;br /&gt;
  public class DesignTimeSummaryViewModelViewModel : SummaryViewModel &lt;br /&gt;
    {&lt;br /&gt;
        public DesignTimeSummaryViewModelViewModel()&lt;br /&gt;
        {&lt;br /&gt;
            Categories = new ObservableCollection&amp;lt;Category&amp;gt;();&lt;br /&gt;
            Categories.Add(new Category() { Name = &amp;#8220;Design Time Test&amp;#8221; }); ;&lt;br /&gt;
            Categories.Add(new Category() { Name = &amp;#8220;Design Time Test 2&amp;#8243; }); ;&lt;br /&gt;
            Categories.Add(new Category() { Name = &amp;#8220;Design Time Test 3&amp;#8243; }); ;&lt;br /&gt;
            MoviesOwned = 10;&lt;br /&gt;
            MoviesCurrentlyRentedOut = 5;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Summary.xaml view (designer info in orange, runtime in blue):&lt;/span&gt;&lt;br /&gt;
&amp;lt;UserControl x:Class=&amp;#8221;MovieRental.UI.MainPage&amp;#8221;&lt;br /&gt;
    xmlns=&amp;#8221;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;#8221;&lt;br /&gt;
    xmlns:x=&amp;#8221;http://schemas.microsoft.com/winfx/2006/xaml&amp;#8221;&lt;br /&gt;
    xmlns:d=&amp;#8221;http://schemas.microsoft.com/expression/blend/2008&amp;#8243;&lt;br /&gt;
    xmlns:mc=&amp;#8221;http://schemas.openxmlformats.org/markup-compatibility/2006&amp;#8243;&lt;br /&gt;
    xmlns:local=&amp;#8221;clr-namespace:MovieRental.UI.ViewModels&amp;#8221;&lt;br /&gt;
    mc:Ignorable=&amp;#8221;d&amp;#8221;&lt;br /&gt;
    d:DesignHeight=&amp;#8221;300&amp;#8243; d:DesignWidth=&amp;#8221;400&amp;#8243;&lt;br /&gt;
&lt;span style="color:rgb(255, 153, 0);"&gt;    d:DataContext=&amp;#8221;{d:DesignInstance Type=local:DesignTimeSummaryViewModelViewModel,IsDesignTimeCreatable=True}&amp;#8221;&lt;/span&gt;&lt;br style="color:rgb(255, 153, 0);"/&gt;&lt;br /&gt;
    &amp;gt;&lt;br /&gt;
&lt;span style="color:rgb(51, 102, 255);"&gt;    &amp;lt;UserControl.Resources&amp;gt;&lt;/span&gt;&lt;br style="color:rgb(51, 102, 255);"/&gt;&lt;br /&gt;
&lt;span style="color:rgb(51, 102, 255);"&gt;        &amp;lt;local:SummaryViewModel x:Key=&amp;#8221;vm&amp;#8221; /&amp;gt;&lt;/span&gt;&lt;br style="color:rgb(51, 102, 255);"/&gt;&lt;br /&gt;
&lt;span style="color:rgb(51, 102, 255);"&gt;    &amp;lt;/UserControl.Resources&amp;gt;&lt;/span&gt;&lt;br style="color:rgb(51, 102, 255);"/&gt;&lt;br /&gt;
&lt;span style="color:rgb(51, 102, 255);"&gt;    &amp;lt;UserControl.DataContext&amp;gt;&lt;/span&gt;&lt;br style="color:rgb(51, 102, 255);"/&gt;&lt;br /&gt;
&lt;span style="color:rgb(51, 102, 255);"&gt;        &amp;lt;Binding Source=&amp;#8221;{StaticResource vm}&amp;#8221; /&amp;gt;&lt;/span&gt;&lt;br style="color:rgb(51, 102, 255);"/&gt;&lt;br /&gt;
&lt;span style="color:rgb(51, 102, 255);"&gt;    &amp;lt;/UserControl.DataContext&amp;gt;&lt;/span&gt;&lt;br style="color:rgb(51, 102, 255);"/&gt;&lt;br /&gt;
    &amp;lt;Grid x:Name=&amp;#8221;LayoutRoot&amp;#8221; Background=&amp;#8221;White&amp;#8221;&amp;gt;&lt;br /&gt;
        &amp;lt;StackPanel&amp;gt;&lt;br /&gt;
            &amp;lt;StackPanel Orientation=&amp;#8221;Horizontal&amp;#8221;&amp;gt;&lt;br /&gt;
                &amp;lt;TextBlock Text=&amp;#8221;Movies Owned&amp;#8221; /&amp;gt;&lt;br /&gt;
                &amp;lt;TextBlock Text=&amp;#8221;{Binding MoviesOwned}&amp;#8221; Padding=&amp;#8221;7,0,0,0&amp;#8243;/&amp;gt;&lt;br /&gt;
        &amp;lt;/StackPanel&amp;gt;&lt;br /&gt;
        &amp;lt;StackPanel Orientation=&amp;#8221;Horizontal&amp;#8221;&amp;gt;&lt;br /&gt;
                &amp;lt;TextBlock Text=&amp;#8221;Movies Rented&amp;#8221;/&amp;gt;&lt;br /&gt;
                &amp;lt;TextBlock Text=&amp;#8221;{Binding MoviesCurrentlyRentedOut}&amp;#8221; Padding=&amp;#8221;7,0,0,0&amp;#8243; /&amp;gt;&lt;br /&gt;
        &amp;lt;/StackPanel&amp;gt;&lt;br /&gt;
            &amp;lt;ListBox ItemsSource=&amp;#8221;{Binding Categories}&amp;#8221; DisplayMemberPath=&amp;#8221;Name&amp;#8221;&amp;gt;&lt;br /&gt;
            &amp;lt;/ListBox&amp;gt;&lt;br /&gt;
        &amp;lt;/StackPanel&amp;gt;&lt;br /&gt;
    &amp;lt;/Grid&amp;gt;&lt;br /&gt;
&amp;lt;/UserControl&amp;gt;&lt;/p&gt;
&lt;p&gt;So far this is working pretty good. The thing that surprised me is that the designer still runs the runtime ViewModels constructor so I had to put a check in around my WCF call to make sure it did not run in the designer via the      System.ComponentModel.DesignerProperties.IsInDesignTool line of code.&lt;/p&gt;</encoded>
      <category>General</category>
    </item>
  </channel>
</rss>
