﻿<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:blogChannel="http://backend.userland.com/blogChannelModule" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
  <channel>
    <title>codeSMART</title>
    <description>Coding, development, general ranting - what more do you want?</description>
    <link>http://blog.darrenoster.com.au/</link>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>BlogEngine.NET 1.6.0.0</generator>
    <language>en-AU</language>
    <blogChannel:blogRoll>http://blog.darrenoster.com.au/opml.axd</blogChannel:blogRoll>
    <blogChannel:blink>http://www.dotnetblogengine.net/syndication.axd</blogChannel:blink>
    <dc:creator>Darren Oster</dc:creator>
    <dc:title>codeSMART</dc:title>
    <geo:lat>0.000000</geo:lat>
    <geo:long>0.000000</geo:long>
    <item>
      <title>A dynamic menu using jQuery and a bit of LINQ magic</title>
      <description>&lt;p&gt;It may be just me (and I’m not prepared to say otherwise), but I seem to get a bit tied in knots sometimes when creating navigation menus for websites in cases where the menu will change depending on whether the user is logged in or not.&amp;#160; The simplest solution (including the menu in-line in the page) has issues once caching is used.&amp;#160; Here’s one solution that has worked well for me.&lt;/p&gt;  &lt;p&gt;First, we create a div within the page as a placeholder.&lt;/p&gt;    &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:a788046b-64f6-4863-88a3-dbf26b2e401c" class="wlWriterEditableSmartContent"&gt;&lt;pre style=" width: 205px; height: 23px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;div &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;id&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;=”navBar”&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;br /&gt;Ensuring we’ve got a reference to jQuery in there, we’ll add the following javascript.





&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:c3426394-558c-4e9d-89ce-210f3b63fa87" class="wlWriterEditableSmartContent"&gt;&lt;pre style=" width: 706px; height: 1023px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF;"&gt;function&lt;/span&gt;&lt;span style="color: #000000;"&gt; createMenu(container, data) {
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;var&lt;/span&gt;&lt;span style="color: #000000;"&gt; div_menu &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; $(document.createElement(&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;div&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;)).addClass(&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;menu&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
    container.append(div_menu);

    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (i &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; data.length; i&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;) {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;var&lt;/span&gt;&lt;span style="color: #000000;"&gt; list &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; $(document.createElement(&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;ul&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;));
        div_menu.append(list);
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;var&lt;/span&gt;&lt;span style="color: #000000;"&gt; listitem &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; createLink(data[i], &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
        list.append(listitem);

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (data[i].Children &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;) {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;var&lt;/span&gt;&lt;span style="color: #000000;"&gt; sublist &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; $(document.createElement(&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;ul&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;));
            listitem.append(sublist);
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (j &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; j &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; data[i].Children.length; j&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;) {
                sublist.append(createLink(data[i].Children[j], &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;false&lt;/span&gt;&lt;span style="color: #000000;"&gt;));
            }
        }
    }
}

&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;function&lt;/span&gt;&lt;span style="color: #000000;"&gt; createLink(data, isMain) {
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;var&lt;/span&gt;&lt;span style="color: #000000;"&gt; link &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; $(document.createElement(&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;a&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;));
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (data.Link &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;) {
        link.attr(&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;href&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;, data.Link);
    }
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt; {
        link.attr(&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;href&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;javascript:void(0);&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
    }
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (data.IsExternal) {
        link.attr(&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;target&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;_blank&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
    }
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;var&lt;/span&gt;&lt;span style="color: #000000;"&gt; txt &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; isMain &lt;/span&gt;&lt;span style="color: #000000;"&gt;?&lt;/span&gt;&lt;span style="color: #000000;"&gt; data.Title.toUpperCase() : data.Title;
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (data.IsExternal) {
        txt &lt;/span&gt;&lt;span style="color: #000000;"&gt;+=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt; &amp;lt;span style=&amp;quot;font-size: xx-small;&amp;quot;&amp;gt;(external link)&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
    }
    link.html(txt);
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (data.Image &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;) {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;var&lt;/span&gt;&lt;span style="color: #000000;"&gt; img &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; $(document.createElement(&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;img&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;));
        img.attr({ &lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;src&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;: data.Image, &lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;alt&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;: &lt;/span&gt;&lt;span style="color: #000000;"&gt;''&lt;/span&gt;&lt;span style="color: #000000;"&gt; });
        link.prepend(img);
    }

    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;var&lt;/span&gt;&lt;span style="color: #000000;"&gt; listitem &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; $(document.createElement(&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;li&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;));
    listitem.append(link);

    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; listitem;
}

&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;function&lt;/span&gt;&lt;span style="color: #000000;"&gt; uncache(url) {
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;var&lt;/span&gt;&lt;span style="color: #000000;"&gt; d &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Date();
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;var&lt;/span&gt;&lt;span style="color: #000000;"&gt; time &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; d.getTime();
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; url &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; ((url.indexOf(&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;?&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;/span&gt;&lt;span style="color: #000000;"&gt;?&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;?&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt; : &lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;time=&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; time;
}

$(document).ready(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;function&lt;/span&gt;&lt;span style="color: #000000;"&gt; () {
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;var&lt;/span&gt;&lt;span style="color: #000000;"&gt; url &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;%= AppHelper.LinkUrl(&amp;quot;~/Home/GetMenuItems&amp;quot;) %&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
    $.post(uncache(url), &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;function&lt;/span&gt;&lt;span style="color: #000000;"&gt; (data) { createMenu($(&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;#navBar&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;), data); });
});
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;



&lt;p&gt;The code is a little tricksy, but not too bad.&amp;#160; There are two main functions, createMenu and createLink.&amp;#160; It should be fairly easy to see how these build the resultant DOM elements.&amp;#160; Obviously you’ll need some CSS in there to make it beautiful.&amp;#160; The uncache function gets around IE’s insistence on caching AJAX calls,&amp;#160; and the whole system is put into action in the document ready function.&amp;#160; In this case, it calls out to an ASP.NET MVC method, which consists of the following code.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:6e3a5f5c-4340-43ff-9178-5cbc32038a77" class="wlWriterEditableSmartContent"&gt;&lt;pre style=" width: 492px; height: 78px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; JsonResult GetMenuItems()
{
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; Json(MenuItems.GetMenu(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;._usersService));
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;This calls a static method on the MenuItems class, passing in a reference to the UsersService class (which is a wrapper around the Membership Provider, giving some handy utilities).&lt;/p&gt;

&lt;p&gt;And the LINQ magic?&amp;#160; It happens here…&lt;/p&gt;



&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:fce1f922-6f8c-4fba-a195-c93edbd2473e" class="wlWriterEditableSmartContent"&gt;&lt;pre style=" width: 795px; height: 982px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF;"&gt;internal&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem
{
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; Title { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; Link { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; Image { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color: #000000;"&gt; IsExternal { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; IList&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;MenuItem&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Children { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; Func&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Included { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }

    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; title, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; link &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; image &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color: #000000;"&gt; isExternal &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;false&lt;/span&gt;&lt;span style="color: #000000;"&gt;, IList&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;MenuItem&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; children &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;, Func&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; included &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Title &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; title;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Link &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; link;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Image &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; image;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.IsExternal &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; isExternal;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Included &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; included;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Children &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; children;
    }
}

&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;internal&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItems
{
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; IList&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;MenuItem&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; menuItems &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; IUsersService _usersService;
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt; padlock &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt;();

    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; IList&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;MenuItem&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; GetMenu(IUsersService usersService)
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (menuItems &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;lock&lt;/span&gt;&lt;span style="color: #000000;"&gt; (padlock)
            {
                _usersService &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; usersService;
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (menuItems &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; _usersService &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
                {
                    BuildMenu();
                }
            }
        }

        var thisMenu &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; menuItems
            .Where(x &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; x.Included &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;||&lt;/span&gt;&lt;span style="color: #000000;"&gt; x.Included())
            .Select(x &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(
                title: x.Title,
                link: x.Link,
                image: x.Image,
                isExternal: x.IsExternal,
                children:
                    x.Children &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;?&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; : x.Children
                        .Where(y &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; y.Included &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;||&lt;/span&gt;&lt;span style="color: #000000;"&gt; y.Included()).Select(y &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(
                            title: y.Title,
                            link: y.Link,
                            image: y.Image,
                            isExternal: y.IsExternal
                    )).ToList()
                )).ToList();

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; thisMenu;
    }

    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; BuildMenu()
    {
        menuItems &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; List&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;MenuItem&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Home&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, AppHelper.LinkUrl(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;~/&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)),

            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Who Are We&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, children: &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; List&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;MenuItem&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; {
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;What We Believe&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, AppHelper.LinkUrl(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;~/Page/WhatWeBelieve&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)),
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;What To Expect&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, AppHelper.LinkUrl(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;~/Page/WhatToExpect&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)),
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Our Staff&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, AppHelper.LinkUrl(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;~/Staff&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)),
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Location &amp;amp;amp; Map&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, AppHelper.LinkUrl(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;~/Home/ContactUs&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;))
            }),

            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Member's Lounge&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, children: &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; List&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;MenuItem&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; {
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Connect Groups&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, AppHelper.LinkUrl(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;~/Home/ConnectGroups&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)),
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Velocity Youth&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, AppHelper.LinkUrl(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;~/Page/Velocity&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)),
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Children's Groups&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, AppHelper.LinkUrl(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;~/Page/ChildrensGroups&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)),
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Audio Sermons&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, AppHelper.LinkUrl(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;~/Sermons&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)),
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Event Calendar&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, AppHelper.LinkUrl(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;~/Calendar&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)),
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Connect09&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;http://connect09.com/&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, AppHelper.ResolveUrl(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Jigsaw-16.png&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;), &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;),
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Registration&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, AppHelper.LinkUrl(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;~/Account/Register&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;), included: &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;delegate&lt;/span&gt;&lt;span style="color: #000000;"&gt;() { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt;_usersService.IsLoggedIn(); })
            }),

            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Baptisms&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, AppHelper.LinkUrl(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;~/Page/Baptism&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)),

            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Contact Us&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, AppHelper.LinkUrl(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;~/Home/ContactUs&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)),

            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Admin&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, included: &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;delegate&lt;/span&gt;&lt;span style="color: #000000;"&gt;() { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; _usersService.IsAdmin(); }, children: &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; List&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;MenuItem&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; {
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;List Users&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, AppHelper.LinkUrl(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;~/Account/ShowUsers&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;), included: &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;delegate&lt;/span&gt;&lt;span style="color: #000000;"&gt;() { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; _usersService.IsSiteAdmin(); }),
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Front Page Manager&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, AppHelper.LinkUrl(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;~/FrontPageManager&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;), included: &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;delegate&lt;/span&gt;&lt;span style="color: #000000;"&gt;() { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; _usersService.IsSiteAdmin(); }),
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MenuItem(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;List Invoices&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, AppHelper.LinkUrl(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;~/Payments/ShowInvoices&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;), included: &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;delegate&lt;/span&gt;&lt;span style="color: #000000;"&gt;() { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; _usersService.IsFinanceAdmin(); })
            })
        };
    }
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;



&lt;p&gt;Okay, there’s a fair bit there.&amp;#160; The MenuItem class should be fairly straightforward.&amp;#160; The Included property is the important one, as this will help determine if a menu item should be shown to this user.&lt;/p&gt;

&lt;p&gt;In MenuItems, the first time GetMenu is called, we use a bit of locking to ensure the menu list is only set up once.&amp;#160; We then create ‘thisMenu’, by calling a (IMHO) nice bit of LINQ which iterates over and filters the possible menu items (set up in BuildMenu) depending on the calculated value of each item’s Included delegate.&lt;/p&gt;

&lt;p&gt;While there are no doubt many other ways to achieve dynamically built menus using ASP.NET MVC, this suits my needs, and may work for you as well.&lt;/p&gt;</description>
      <link>http://blog.darrenoster.com.au/post/A-dynamic-menu-using-jQuery-and-a-bit-of-LINQ-magic.aspx</link>
      <author>daggmano</author>
      <comments>http://blog.darrenoster.com.au/post/A-dynamic-menu-using-jQuery-and-a-bit-of-LINQ-magic.aspx#comment</comments>
      <guid>http://blog.darrenoster.com.au/post.aspx?id=5132231e-c064-4318-b0cf-0b3aa436dd2d</guid>
      <pubDate>Fri, 03 Sep 2010 18:07:19 +0500</pubDate>
      <category>Coding</category>
      <dc:publisher>daggmano</dc:publisher>
      <pingback:server>http://blog.darrenoster.com.au/pingback.axd</pingback:server>
      <pingback:target>http://blog.darrenoster.com.au/post.aspx?id=5132231e-c064-4318-b0cf-0b3aa436dd2d</pingback:target>
      <slash:comments>14312</slash:comments>
      <trackback:ping>http://blog.darrenoster.com.au/trackback.axd?id=5132231e-c064-4318-b0cf-0b3aa436dd2d</trackback:ping>
      <wfw:comment>http://blog.darrenoster.com.au/post/A-dynamic-menu-using-jQuery-and-a-bit-of-LINQ-magic.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.darrenoster.com.au/syndication.axd?post=5132231e-c064-4318-b0cf-0b3aa436dd2d</wfw:commentRss>
    </item>
    <item>
      <title>The ASP.NET Membership Provider and FluentMigrator</title>
      <description>&lt;p&gt;I’ve been looking at the idea of storing database schema changes along with source code in Mercurial.&amp;#160; Now, database change management seems to be a non-trivial issue.&amp;#160; There are some good tools around, including Visual Studio (Premium or Ultimate editions), but my weapon of choice ended up being &lt;a href="http://github.com/schambers/fluentmigrator"&gt;FluentMigrator&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The next issue was that the project I was working on used the ASP.NET Membership Provider model, which requires (in its default implementation) a whole bucket load of tables, stored procedures and views.&amp;#160; These are normally taken care of by running aspnet_regsql.exe, but I really wanted a solution where I could just create a brand new blank database, run my application, and have the entire schema ready to go.&amp;#160; To achieve this meant that the aforementioned bucket of tables,&amp;#160; stored procedures and views would need to be created from a migration script.&lt;/p&gt;  &lt;p&gt;After several attempts, I am able to say that the idea worked!&amp;#160; Further, if you feel that this is something you might like to try out, I have made the source code for the migration available at the URL below.&lt;/p&gt;  &lt;p&gt;Now, before I finish, I must put in a heavy disclaimer.&amp;#160; I have not done extensive testing with this migration script, and do not know enough about the ASP.NET Membership Provider model to be sure that future updates to SQL Server and /or the .NET Framework will cause issues here.&amp;#160; All I can say is that it works for me, and has worked using SQL Server 2008, SQL Server 2008 R2, .NET 3.5 SP1 and .NET 4.&lt;/p&gt;  &lt;p&gt;Here’s the URL for the code: &lt;a title="http://cid-6bd010a81465a625.skydrive.live.com/redir.aspx?page=self&amp;amp;type=3&amp;amp;client=wnf&amp;amp;resId=6BD010A81465A625!150" href="http://cid-6bd010a81465a625.skydrive.live.com/redir.aspx?page=self&amp;amp;type=3&amp;amp;client=wnf&amp;amp;resId=6BD010A81465A625!150"&gt;http://cid-6bd010a81465a625.skydrive.live.com/redir.aspx?page=self&amp;amp;type=3&amp;amp;client=wnf&amp;amp;resId=6BD010A81465A625!150&lt;/a&gt;&lt;/p&gt;</description>
      <link>http://blog.darrenoster.com.au/post/The-ASPNET-Membership-Provider-and-FluentMigrator.aspx</link>
      <author>daggmano</author>
      <comments>http://blog.darrenoster.com.au/post/The-ASPNET-Membership-Provider-and-FluentMigrator.aspx#comment</comments>
      <guid>http://blog.darrenoster.com.au/post.aspx?id=72d4e99a-4cf7-45c8-bb70-6bbbfcbab0d7</guid>
      <pubDate>Fri, 13 Aug 2010 16:19:48 +0500</pubDate>
      <category>Coding</category>
      <dc:publisher>daggmano</dc:publisher>
      <pingback:server>http://blog.darrenoster.com.au/pingback.axd</pingback:server>
      <pingback:target>http://blog.darrenoster.com.au/post.aspx?id=72d4e99a-4cf7-45c8-bb70-6bbbfcbab0d7</pingback:target>
      <slash:comments>7825</slash:comments>
      <trackback:ping>http://blog.darrenoster.com.au/trackback.axd?id=72d4e99a-4cf7-45c8-bb70-6bbbfcbab0d7</trackback:ping>
      <wfw:comment>http://blog.darrenoster.com.au/post/The-ASPNET-Membership-Provider-and-FluentMigrator.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.darrenoster.com.au/syndication.axd?post=72d4e99a-4cf7-45c8-bb70-6bbbfcbab0d7</wfw:commentRss>
    </item>
    <item>
      <title>A brief update</title>
      <description>&lt;p&gt;I recently received an email from &lt;a href="http://adamcogan.com/" target="_blank"&gt;Adam Cogan&lt;/a&gt;.&amp;#160; Four simple words said, “You should blog more.”&lt;/p&gt;  &lt;p&gt;Now, when Adam Cogan speaks, I listen.&amp;#160; Unless he’s talking about SharePoint or TFS, in which case I might tune out a little.&amp;#160; So I guess you could say I listen to a small portion of what he says.&lt;/p&gt;  &lt;p&gt;Nevertheless, I had been thinking that my blogging was a little lax of late anyway, so thought I would take this opportunity to write a little about what I’ve been up to.&lt;/p&gt;  &lt;p&gt;My job, which for a few years has kept me busy in the land of .NET / C# / WPF, has recently taken me in a new direction.&amp;#160; I’m working on developing applications for Panasonic’s Vieracast platform.&amp;#160; The applications are developed using object-oriented Javascript, which is something I never even knew existed until a few months ago.&amp;#160; Shame on me!&amp;#160; My first few efforts resulted in code that I hope never sees the light of day, but I’ve started leveraging tools and principles learned from my years of .NET coding and am now cranking out some pretty neat stuff.&amp;#160; When the code goes into production I might blog a little more about the project, but for now it’s all under pretty strict NDA.&lt;/p&gt;  &lt;p&gt;The &lt;a href="http://glenmorepark.anglican.asn.au/" target="_blank"&gt;Glenmore Park Anglican Church website&lt;/a&gt; hasn’t seen too many updates recently, and the reason is that I’m spending time refactoring the underlying models and structures to make future enhancements easier.&amp;#160; One part of this is to put the database schema under source control by using &lt;a href="http://github.com/schambers/fluentmigrator/" target="_blank"&gt;FluentMigrator&lt;/a&gt; to look after versioning.&amp;#160; Because I’m using Microsoft’s ASP.NET Membership Provider model for authentication (with the database schema associated with this), I’ve been spending some time creating the ASP.NET Membership Provider database schema as a FluentMigrator migration.&amp;#160; Once this is complete, I’ll make the code available online for those who would like to add this capability to their projects.&lt;/p&gt;  &lt;p&gt;The last exciting bit of news (for me, at least) is the purchase of brand spanking new Apple PowerBook Pro (Intel i7 CPU, 8GB RAM, 17” 1920x1200 screen).&amp;#160; As I write, the machine is “Prepared for Shipment”.&amp;#160; Moving to Mac has been something that’s taken a lot of thought, but recent experiences with running virtual machines using &lt;a href="http://www.virtualbox.org/" target="_blank"&gt;VirtualBox&lt;/a&gt; (plus the announcement that Steam is now available for Mac) have given me the confidence to move over.&amp;#160; At this stage I intend to run OSX as the host environment and use Win7 VMs for development, and hope to write a couple articles detailing how this pans out.&lt;/p&gt;  &lt;p&gt;So there you go, Adam.&amp;#160; Until next time…&lt;/p&gt;</description>
      <link>http://blog.darrenoster.com.au/post/A-brief-update.aspx</link>
      <author>daggmano</author>
      <comments>http://blog.darrenoster.com.au/post/A-brief-update.aspx#comment</comments>
      <guid>http://blog.darrenoster.com.au/post.aspx?id=62e103a9-1b87-4d37-9be9-b674c9509766</guid>
      <pubDate>Mon, 17 May 2010 04:15:14 +0500</pubDate>
      <category>Miscellaneous</category>
      <dc:publisher>daggmano</dc:publisher>
      <pingback:server>http://blog.darrenoster.com.au/pingback.axd</pingback:server>
      <pingback:target>http://blog.darrenoster.com.au/post.aspx?id=62e103a9-1b87-4d37-9be9-b674c9509766</pingback:target>
      <slash:comments>5824</slash:comments>
      <trackback:ping>http://blog.darrenoster.com.au/trackback.axd?id=62e103a9-1b87-4d37-9be9-b674c9509766</trackback:ping>
      <wfw:comment>http://blog.darrenoster.com.au/post/A-brief-update.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.darrenoster.com.au/syndication.axd?post=62e103a9-1b87-4d37-9be9-b674c9509766</wfw:commentRss>
    </item>
    <item>
      <title>Developing for the S60 5th edition</title>
      <description>&lt;p&gt;I recently upgraded my mobile phone to a Nokia N97 mini, which runs the S60 5th edition platform.&amp;#160; I had previously attempted developing software for the S60 platform 3rd edition – without much success – and thought I’d give the new platform a go.&lt;/p&gt;  &lt;p&gt;However, while there are several tutorials out there for people starting to develop with the Qt toolset (particularly on the Qt site), there seemed to be little in the way of basic tutorials for native C++ development.&amp;#160; So I shall attempt to present a simple tutorial here.&lt;/p&gt;  &lt;h3&gt;What do I need?&lt;/h3&gt;  &lt;p&gt;You will need to download and install the following tools:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.forum.nokia.com/info/sw.nokia.com/id/ec866fab-4b76-49f6-b5a5-af0631419e9c/S60_All_in_One_SDKs.html" target="_blank"&gt;S60 Platform and Device SDKs for Symbian OS&lt;/a&gt;       &lt;br /&gt;Choose the correct SDK for your platform.&amp;#160; I chose the N97 SDK. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.forum.nokia.com/info/sw.nokia.com/id/dbb8841d-832c-43a6-be13-f78119a2b4cb.html" target="_blank"&gt;Carbide.c++&lt;/a&gt;       &lt;br /&gt;I have version 2.3. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.activestate.com/activeperl/downloads/" target="_blank"&gt;ActivePerl&lt;/a&gt;       &lt;br /&gt;Most S60 docs will say you need ActivePerl 5.6.1.&amp;#160; I have 5.10.1 and it works fine for me, providing you &lt;a href="http://wiki.forum.nokia.com/index.php/KIS001302_-_Compiling_context-sensitive_help_fails_with_latest_version_of_Perl" target="_blank"&gt;follow the instructions here&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.comms.ovi.com/m/p/ovi/suite/English" target="_blank"&gt;Nokia Ovi Suite&lt;/a&gt;       &lt;br /&gt;This is used to install your apps on the phone. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;You will also need the Java Runtime Engine installed (I’ve got the latest version and it all works fine), but you’ve probably already got that.&lt;/p&gt;  &lt;p&gt;One issue I found was that development on a Virtual PC image didn’t work, mainly due to issues with the N97 Emulator failing on startup.&amp;#160; I don’t know how this would work with VMWare, and your mileage may vary anyway.&lt;/p&gt;  &lt;h3&gt;What are we making?&lt;/h3&gt;  &lt;p&gt;The tutorials I have seen for Qt basically create a listbox, a textbox, a button to add the text from the textbox into the listbox, and another button to clear the listbox.&amp;#160; This sounds like a good start, but we’ll make it with a slight change, which you’ll see as we go on.&lt;/p&gt;  &lt;h3&gt;Let’s begin…&lt;/h3&gt;  &lt;p&gt;Okay, start by launching Carbide.c++.&amp;#160; Being an Eclipse-based IDE, it will ask for a workspace to use.&amp;#160; Just select the default for now.&lt;/p&gt;  &lt;p&gt;Once Carbide has started, create a New Symbian OS C++ Project.&amp;#160; From the template options, choose the S60 GUI Application with UI Designer.&amp;#160; Following this, type in your project name (say, MyTextList).&amp;#160; Next, you will be asked to select your target SDK and Build Configurations.&amp;#160; If you only have one SDK installed, this should be the default, otherwise you will need to choose your target.&amp;#160; Next, select your target language.&lt;/p&gt;  &lt;p&gt;Following this, you will be given the option to select a design template.&amp;#160; I have chosen to go with the Empty design, to give a better overview of the design process.&amp;#160; Next, you can change the Container Name and Type if you wish.&amp;#160; Just accept the defaults and all should be fine.&amp;#160; On the Basic Settings screen, feel free to change settings if you wish, or just accept the defaults.&amp;#160; The same applies to the Project Directories, and that (finally) finishes the Project Wizard.&lt;/p&gt;  &lt;h3&gt;Designing the UI&lt;/h3&gt;  &lt;p&gt;In the UI Designer (MyTextListContainer.uidesign), you can change the window title if you wish, just by clicking on the text.&amp;#160; Change it to My Text List.&amp;#160; Now, in the main area of the window, we want to drag a List Box from the Controls group.&amp;#160; Note, if you add anything else (such as a Button), the List Box will disappear from this list.&amp;#160; Because the List Box takes up the entire client area, we will deviate from the Qt design and put the Add Text / Clear Items options in the menu rather than as separate controls.&lt;/p&gt;  &lt;p&gt;We will also need a dialog to allow the user to input text, so drag a Single-line Data Query (from the Notes and Dialogs group) to the bottom panel of the designer.&amp;#160; Select this in the lower panel, then click on the Text Edit control in the dialog (where it says Edit text).&amp;#160; Go to the Properties tab, and change the maximum length parameter to 20.&lt;/p&gt;  &lt;p&gt;Select the optionsMenu control from the lower panel in the designer, which will give you the ability to type menu items.&amp;#160; Add a couple items for Add Text and Clear Items.&lt;/p&gt;  &lt;p&gt;Right-click on the Add Text menu item and select the Handle ‘selected’ Event option.&amp;#160; Say Yes to the dialog box and we can start throwing in some code.&lt;/p&gt;  &lt;h3&gt;Handling the Add Text event&lt;/h3&gt;  &lt;p&gt;Inside the HandleAdd_TextMenuItemSelectedL method, we want to open an edit dialog, allow the user to enter text,and if this returns okay, insert the text into the list.&amp;#160; This bit took the longest to work out, but here’s the code:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;TBool CMyTextListContainerView::HandleAdd_TextMenuItemSelectedL( TInt aCommand )
    {
    _LIT(STRFMT, &lt;span class="str"&gt;&amp;quot;\t%S\t\t&amp;quot;&lt;/span&gt;);
    
    TBuf&amp;lt;20&amp;gt; text;
    TBuf&amp;lt;30&amp;gt; itemText;
    
    TInt retval = &lt;span class="kwrd"&gt;this&lt;/span&gt;-&amp;gt;RunDataQuery1L(text, &lt;span class="kwrd"&gt;true&lt;/span&gt;, NULL);
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (retval == EEikBidOk)
        {
            CAknSingleStyleListBox *listBox = &lt;span class="kwrd"&gt;this&lt;/span&gt;-&amp;gt;iMyTextListContainer-&amp;gt;ListBox();
            
            MDesC16Array *textArray = listBox-&amp;gt;Model()-&amp;gt;ItemTextArray();
            CDesCArray *itemList = static_cast&amp;lt;CDesCArray*&amp;gt;(textArray);
            
            itemText.Format(STRFMT, &amp;amp;text);
            itemList-&amp;gt;AppendL(itemText);
            
            listBox-&amp;gt;HandleItemAdditionL();
        }
    &lt;span class="kwrd"&gt;return&lt;/span&gt; ETrue;
    }&lt;/pre&gt;

&lt;p&gt;This starts by setting up a format string for the list item and a few local variables.&amp;#160; We then open the text input dialog.&amp;#160; The return value for this depends on whether the OK or Cancel button was pressed, so we check for the OK value.&amp;#160; Note that we don’t need to check for a null value in the text field, as the OK button is not displayed when the text box is empty.&lt;/p&gt;

&lt;p&gt;We then get a reference to the List Box control, then to it’s Item Text Array (note that S60 development generally follows an MVC (Model-View-Controller) framework, so we add the item to the Text Box’s model, not the Text Box itself).&amp;#160; This reference is then cast to a string array.&lt;/p&gt;

&lt;p&gt;The input text is then written out to the correct format (&lt;a href="http://www.newlc.com/en/Listbox-Part-II.html" target="_blank"&gt;see this page&lt;/a&gt; for a description of the various formats) and appended to the item list.&amp;#160; We then let the List Box know that it needs to update itself with a call to HandleItemAdditionL().&lt;/p&gt;

&lt;p&gt;Check that the build is targeted on the Emulator build (right-click the project, and check the Build Configurations &amp;gt; Set Active), and build and run the app.&amp;#160; Accept any defaults in any dialogs that pop up, and you should see the emulator pop up running your app!&amp;#160; At this point you should be able to add items to the text box, but the Clear Items menu item won’t work.&amp;#160; Exit the emulator and we’ll finish things off.&lt;/p&gt;

&lt;h3&gt;Clearing the List Box&lt;/h3&gt;

&lt;p&gt;Jump back to the MyTextListContainer.uidesign window.&amp;#160; Click on the optionsMenu in the lower pane, then right-click the Clear Items menu item and Handle the ‘selected’ Event.&amp;#160; Again, go to the code, and add the following to the method:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;TBool CMyTextListContainerView::HandleClear_ItemsMenuItemSelectedL( TInt aCommand )
    {
    CAknSingleStyleListBox *listBox = &lt;span class="kwrd"&gt;this&lt;/span&gt;-&amp;gt;iMyTextListContainer-&amp;gt;ListBox();
    
    MDesC16Array *textArray = listBox-&amp;gt;Model()-&amp;gt;ItemTextArray();
    CDesCArray *itemList = static_cast&amp;lt;CDesCArray*&amp;gt;(textArray);
    
    itemList-&amp;gt;Reset();
    listBox-&amp;gt;Reset();
    
    listBox-&amp;gt;HandleItemRemovalL();
    listBox-&amp;gt;DrawNow();
    
    &lt;span class="kwrd"&gt;return&lt;/span&gt; ETrue;
    }&lt;/pre&gt;

&lt;p&gt;Again, we grab a reference to the List Box and its Item Text Array.&amp;#160; We reset the Item List, reset the List Box, and then call HandleItemRemovalL().&amp;#160; One additional step I needed (although I’m not sure why it is needed) was to call DrawNow() on the List Box.&lt;/p&gt;

&lt;p&gt;Once again, run this up in the emulator and make sure everything works as expected.&lt;/p&gt;

&lt;h3&gt;Deploying to your phone&lt;/h3&gt;

&lt;p&gt;To create a file suitable for deployment to your phone, right-click the project in the Project Explorer, go to Build Configurations &amp;gt; Set Active, and select Phone Release (GCCE) for your SDK.&amp;#160; To see the details of the build configuration, right-click the project, select Properties, and go to Carbide.c++ &amp;gt; Build Configurations.&amp;#160; The defaults should be fine.&lt;/p&gt;

&lt;p&gt;Build the project, and then browse (in the Project Explorer) to the sis folder.&amp;#160; Here, you should find the MyTextList.sis and MyTextList.sisx files.&amp;#160; Assuming you have previously connected you phone to Ovi Suite and have the Suite running on your PC, double-click the .sisx file.&amp;#160; This should start the Ovi Suite program installer automatically and allow you to install the application on your phone.&lt;/p&gt;

&lt;p&gt;For some reason on the N97 mini the phone complained that the app may not be compatible with my phone.&amp;#160; This may mean that I should be running the normal S60 5th edition SDK rather than the N97 SDK, but it all works anyway.&lt;/p&gt;

&lt;p&gt;I hope this helps with your S60 development.&amp;#160; Please let me know what you think.&lt;/p&gt;</description>
      <link>http://blog.darrenoster.com.au/post/Developing-for-the-S60-5th-edition.aspx</link>
      <author>daggmano</author>
      <comments>http://blog.darrenoster.com.au/post/Developing-for-the-S60-5th-edition.aspx#comment</comments>
      <guid>http://blog.darrenoster.com.au/post.aspx?id=dd5a3644-5de2-4e18-8fba-c39bb54de807</guid>
      <pubDate>Sat, 27 Feb 2010 14:27:30 +0500</pubDate>
      <category>Mobile Development</category>
      <dc:publisher>daggmano</dc:publisher>
      <pingback:server>http://blog.darrenoster.com.au/pingback.axd</pingback:server>
      <pingback:target>http://blog.darrenoster.com.au/post.aspx?id=dd5a3644-5de2-4e18-8fba-c39bb54de807</pingback:target>
      <slash:comments>17595</slash:comments>
      <trackback:ping>http://blog.darrenoster.com.au/trackback.axd?id=dd5a3644-5de2-4e18-8fba-c39bb54de807</trackback:ping>
      <wfw:comment>http://blog.darrenoster.com.au/post/Developing-for-the-S60-5th-edition.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.darrenoster.com.au/syndication.axd?post=dd5a3644-5de2-4e18-8fba-c39bb54de807</wfw:commentRss>
    </item>
    <item>
      <title>Implementing INotifyPropertyChanged</title>
      <description>&lt;p&gt;Binding in WPF is a massive improvement on previous efforts, and the power offered by the INotifyPropertyChanged interface in its ability to transform a POCO (Plain Old CLR Object) into a binding partner is pretty magical.&lt;/p&gt;  &lt;p&gt;So what does INotifyPropertyChanged require of us?&amp;#160; Not much, really.&amp;#160; The basic implementation of the interface is as simple as the following line of code:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;event&lt;/span&gt; PropertyChangedEventHandler PropertyChanged;&lt;/pre&gt;

&lt;p&gt;We can now add the following to our property setters to cause WPF to notice any value changes:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; foo;

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Foo
{
    get { &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.foo; }
    set
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.foo != &lt;span class="kwrd"&gt;value&lt;/span&gt;)
        {
            &lt;span class="kwrd"&gt;this&lt;/span&gt;.foo = &lt;span class="kwrd"&gt;value&lt;/span&gt;;
            this.PropertyChanged(&lt;span class="kwrd"&gt;this&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; PropertyChangedEventArgs(&lt;span class="str"&gt;&amp;quot;Foo&amp;quot;&lt;/span&gt;));
        }
    }
}&lt;/pre&gt;

&lt;p&gt;But what happens if the PropertyChanged event hasn’t had a handler wired in?&amp;#160; PropertyChanged is null, so the setter falls over.&amp;#160; No problem, here’s attempt #2:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;set
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.foo != &lt;span class="kwrd"&gt;value&lt;/span&gt;)
    {
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.foo = &lt;span class="kwrd"&gt;value&lt;/span&gt;;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.PropertyChanged != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
        {
            &lt;span class="kwrd"&gt;this&lt;/span&gt;.PropertyChanged(&lt;span class="kwrd"&gt;this&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; PropertyChangedEventArgs(&lt;span class="str"&gt;&amp;quot;Foo&amp;quot;&lt;/span&gt;));
        }
    }
}&lt;/pre&gt;

&lt;p&gt;OK, so since we’ll probably have more than one property in a class, we can wrap this up in a helper method.&amp;#160; Enter attempt #3:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; foo;

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Foo
{
    get { &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.foo; }
    set
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.foo != &lt;span class="kwrd"&gt;value&lt;/span&gt;)
        {
            &lt;span class="kwrd"&gt;this&lt;/span&gt;.foo = &lt;span class="kwrd"&gt;value&lt;/span&gt;;
            &lt;span class="kwrd"&gt;this&lt;/span&gt;.OnPropertyChanged(&lt;span class="str"&gt;&amp;quot;Foo&amp;quot;&lt;/span&gt;);
        }
    }
}

&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnPropertyChanged(&lt;span class="kwrd"&gt;string&lt;/span&gt; label)
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.PropertyChanged != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
    {
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.PropertyChanged(&lt;span class="kwrd"&gt;this&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; PropertyChangedEventArgs(label));
    }
}&lt;/pre&gt;

&lt;p&gt;We can do better, though.&amp;#160; Notice that every time this method is called, a new PropertyChangedEventArgs instance is being created.&amp;#160; This instance is dependent only on the label of the property, so maybe we can bring an EventArg cache into play.&amp;#160; Attempt #4 coming up:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, PropertyChangedEventArgs&amp;gt; eventArgs = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, PropertyChangedEventArgs&amp;gt;();

&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnPropertyChanged(&lt;span class="kwrd"&gt;string&lt;/span&gt; label)
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.PropertyChanged != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (!&lt;span class="kwrd"&gt;this&lt;/span&gt;.eventArgs.ContainsKey(label))
        {
            &lt;span class="kwrd"&gt;this&lt;/span&gt;.eventArgs.Add(label, &lt;span class="kwrd"&gt;new&lt;/span&gt; PropertyChangedEventArgs(label));
        }

        &lt;span class="kwrd"&gt;this&lt;/span&gt;.PropertyChanged(&lt;span class="kwrd"&gt;this&lt;/span&gt;, &lt;span class="kwrd"&gt;this&lt;/span&gt;.eventArgs[label]);
    }
}&lt;/pre&gt;

&lt;p&gt;In fact, since the PropertyChangedEventArgs depends ONLY on the label, there’s no reason why we can’t make this a static (shared) collection.&amp;#160; Attempt #5:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, PropertyChangedEventArgs&amp;gt; eventArgs = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, PropertyChangedEventArgs&amp;gt;();

&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnPropertyChanged(&lt;span class="kwrd"&gt;string&lt;/span&gt; label)
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.PropertyChanged != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (!MyClass.eventArgs.ContainsKey(label))
        {
            MyClass.eventArgs.Add(label, &lt;span class="kwrd"&gt;new&lt;/span&gt; PropertyChangedEventArgs(label));
        }

        &lt;span class="kwrd"&gt;this&lt;/span&gt;.PropertyChanged(&lt;span class="kwrd"&gt;this&lt;/span&gt;, MyClass.eventArgs[label]);
    }
}&lt;/pre&gt;

&lt;p&gt;We’re getting close now, I can feel it!&amp;#160; But what happens if a couple threads try to update a property at the same time?&amp;#160; We don’t want to fail because two identical keys are added, so let’s add some locking.&amp;#160; Attempt #6:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; static Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, PropertyChangedEventArgs&amp;gt; eventArgs = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, PropertyChangedEventArgs&amp;gt;();

&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnPropertyChanged(&lt;span class="kwrd"&gt;string&lt;/span&gt; label)
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.PropertyChanged != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (!MyClass.eventArgs.ContainsKey(label))
        {
            &lt;span class="kwrd"&gt;lock&lt;/span&gt; (MyClass.eventArgs)
            {
                MyClass.eventArgs.Add(label, &lt;span class="kwrd"&gt;new&lt;/span&gt; PropertyChangedEventArgs(label));
            }
        }

        &lt;span class="kwrd"&gt;this&lt;/span&gt;.PropertyChanged(&lt;span class="kwrd"&gt;this&lt;/span&gt;, MyClass.eventArgs[label]);
    }
}&lt;/pre&gt;

&lt;p&gt;Of course, there is one problem here too.&amp;#160; What if two threads arrive at the lock at the same time?&amp;#160; One will get in and add the new item, while the other will wait.&amp;#160; When the lock is released, the other thread will get the lock and … add the same item!&amp;#160; So, one more check is needed inside the lock.&amp;#160; Attempt #7:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; static Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, PropertyChangedEventArgs&amp;gt; eventArgs = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, PropertyChangedEventArgs&amp;gt;();

&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnPropertyChanged(&lt;span class="kwrd"&gt;string&lt;/span&gt; label)
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.PropertyChanged != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (!MyClass.eventArgs.ContainsKey(label))
        {
            &lt;span class="kwrd"&gt;lock&lt;/span&gt; (MyClass.eventArgs)
            {
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (!MyClass.eventArgs.ContainsKey(label))
                {
                    MyClass.eventArgs.Add(label, &lt;span class="kwrd"&gt;new&lt;/span&gt; PropertyChangedEventArgs(label));
                }
            }
        }

        &lt;span class="kwrd"&gt;this&lt;/span&gt;.PropertyChanged(&lt;span class="kwrd"&gt;this&lt;/span&gt;, MyClass.eventArgs[label]);
    }
}&lt;/pre&gt;

&lt;p&gt;And that should do it!&amp;#160; Have fun.&lt;/p&gt;</description>
      <link>http://blog.darrenoster.com.au/post/Implementing-INotifyPropertyChanged.aspx</link>
      <author>daggmano</author>
      <comments>http://blog.darrenoster.com.au/post/Implementing-INotifyPropertyChanged.aspx#comment</comments>
      <guid>http://blog.darrenoster.com.au/post.aspx?id=65cbb878-110e-490e-8e43-3b02120b04a0</guid>
      <pubDate>Thu, 11 Feb 2010 08:30:43 +0500</pubDate>
      <category>Coding</category>
      <dc:publisher>daggmano</dc:publisher>
      <pingback:server>http://blog.darrenoster.com.au/pingback.axd</pingback:server>
      <pingback:target>http://blog.darrenoster.com.au/post.aspx?id=65cbb878-110e-490e-8e43-3b02120b04a0</pingback:target>
      <slash:comments>22659</slash:comments>
      <trackback:ping>http://blog.darrenoster.com.au/trackback.axd?id=65cbb878-110e-490e-8e43-3b02120b04a0</trackback:ping>
      <wfw:comment>http://blog.darrenoster.com.au/post/Implementing-INotifyPropertyChanged.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.darrenoster.com.au/syndication.axd?post=65cbb878-110e-490e-8e43-3b02120b04a0</wfw:commentRss>
    </item>
    <item>
      <title>Streaming large files using WCF - Part 2</title>
      <description>&lt;p&gt;This is the second in a series of articles in which I walk through the process of creating a WCF service and client application for streaming large (several gigabytes) files across a network.&amp;nbsp; The articles are presented as below:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Creating the Server Application - 1 &lt;/li&gt;
&lt;li&gt;Creating the Server Application - 2 (this article) &lt;/li&gt;
&lt;li&gt;Creating the Client Application &lt;/li&gt;
&lt;li&gt;Creating an Installer for the Server &lt;/li&gt;
&lt;li&gt;Adding Extra Functionality &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Please note the disclaimer in the first article before implementing this code.&lt;/p&gt;
&lt;h3&gt;Finishing the Server Application&lt;/h3&gt;
&lt;p&gt;With all of the classes for WCF defined, it is time to implement the guts of the service.&amp;nbsp; Early in part 1 of this series, we created a WCF Service Library called WCFFileStreamerService.&amp;nbsp; In here, delete IService1.cs and Service1.cs, and add a reference to the WCFFileStreamerTypes project.&amp;nbsp; Add a new class to this service called FileTransferService which implements the IFileTransferService interface.&lt;/p&gt;
&lt;h3&gt;The License Key&lt;/h3&gt;
&lt;p&gt;You may remember that each Request message in our service had a LicenseKey property.&amp;nbsp; While this can be implemented in a variety of ways, we'll just use a static string for now.&amp;nbsp; Open the Properties window for the WCFFileStreamerService project, and in Settings, add a default settings file (if required), and then add an Application-scoped string named LicenseKey.&amp;nbsp; Set this value to a secret key, such as 'p@ssw0rd'.&amp;nbsp; Sneaky, huh?&amp;nbsp; While you're at it, add another string named StreamStoragePath and set it to the path where files will be streamed from / to.&amp;nbsp; This will eventually be set specifically for the server, but for testing on your development box it will need to be a local path.&amp;nbsp; We're now ready to implement our service methods.&lt;/p&gt;
&lt;h3&gt;The Service Methods&lt;/h3&gt;
&lt;p&gt;Go back to the FileTransferService class.&amp;nbsp; Each method should test the LicenseKey property of the request, so add the following code to each method (of course, you could add a private method and call that from each method - the choice is up to you):&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (request.LicenseKey != Settings.Default.LicenseKey) 
{ 
    &lt;span class="kwrd"&gt;const&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; reason = &lt;span class="str"&gt;"Incorrect License Key provided."&lt;/span&gt;; 
    &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; FaultException&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(reason, reason); 
} &lt;/pre&gt;
&lt;p&gt;&lt;!-- .csharpcode, .csharpcode pre { 	font-size: small; 	color: black; 	font-family: consolas, "Courier New", courier, monospace; 	background-color: #ffffff; 	/*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt  { 	background-color: #f4f4f4; 	width: 100%; 	margin: 0em; } .csharpcode .lnum { color: #606060; } --&gt;&lt;/p&gt;
&lt;h3&gt;GetFreeSpace&lt;/h3&gt;
&lt;p&gt;The GetFreeSpace method is a handy method for getting the free space on the target drive on the server.&amp;nbsp; The code is as follows:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;long&lt;/span&gt; retval = 0;

var storagePath = Settings.Default.StreamStoragePath;
var storageDrive = Path.GetPathRoot(storagePath).Substring(0, 2);

&lt;span class="kwrd"&gt;try&lt;/span&gt;
{
    SelectQuery query = &lt;span class="kwrd"&gt;new&lt;/span&gt; SelectQuery(&lt;span class="str"&gt;"SELECT * FROM Win32_LogicalDisk WHERE Name = '"&lt;br /&gt;&lt;/span&gt;                                                            + storageDrive + &lt;span class="str"&gt;"'"&lt;/span&gt;);
    ManagementObjectSearcher searcher = &lt;span class="kwrd"&gt;new&lt;/span&gt; ManagementObjectSearcher(query);

    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (ManagementObject mo &lt;span class="kwrd"&gt;in&lt;/span&gt; searcher.Get())
    {
        retval = Convert.ToInt64(mo[&lt;span class="str"&gt;"FreeSpace"&lt;/span&gt;].ToString());
    }
}
&lt;span class="kwrd"&gt;catch&lt;/span&gt;
{
}

GetFreeSpaceResponse response = &lt;span class="kwrd"&gt;new&lt;/span&gt; GetFreeSpaceResponse();
response.FreeSpace = retval;

&lt;span class="kwrd"&gt;return&lt;/span&gt; response;&lt;/pre&gt;
&lt;p&gt;&lt;!-- .csharpcode, .csharpcode pre { 	font-size: small; 	color: black; 	font-family: consolas, "Courier New", courier, monospace; 	background-color: #ffffff; 	/*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt  { 	background-color: #f4f4f4; 	width: 100%; 	margin: 0em; } .csharpcode .lnum { color: #606060; } --&gt;&lt;/p&gt;
&lt;p&gt;You'll need a reference to System.Management for the SelectQuery &amp;amp; ManagementObject stuff.&lt;/p&gt;
&lt;h3&gt;Upload Service Methods&lt;/h3&gt;
&lt;p&gt;The upload portion of the service has three methods: an InitializeUpload method to prepare the server for the stream to come, a GetUploadStatus method so that the client can check on the upload progress, and a CancelUploadAync method so that the client can cancel the upload.&amp;nbsp; These last two methods are not required for downloading for reasons that will hopefully become apparent.&amp;nbsp; Here are the methods:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; InitUploadResponse InitializeUpload(InitUploadRequest request)
{
    ... LicenseKey test goes here ...

    var status = &lt;span class="kwrd"&gt;new&lt;/span&gt; InitializeStatus();
    status.UploadID = Guid.NewGuid();
    status.Length = request.Length;
    status.ServerLength = 0L;

    UploadStatusManager.Instance.AddNewItem(status.UploadID);

    FileInfo fi = &lt;span class="kwrd"&gt;new&lt;/span&gt; FileInfo(Path.Combine(&lt;br /&gt;                               Settings.Default.StreamStoragePath, request.FileName));
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (fi.Exists)
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (fi.Length &amp;lt; request.Length)
        {
            status.Status = InitStatus.ExistsAndResumable;
            status.ServerLength = fi.Length;
        }
        &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (fi.Length &amp;gt; request.Length)
        {
            status.Status = InitStatus.ExistsNonMatchingHash;
        }
        &lt;span class="kwrd"&gt;else&lt;/span&gt;
        {
            &lt;span class="rem"&gt;// Lengths match, so check hash...&lt;/span&gt;
            &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] hash;
            &lt;span class="kwrd"&gt;using&lt;/span&gt; (Stream s = fi.OpenRead())
            {
                hash = SHA1Helper.SHA1Helper.HashFile(s);
            }

            &lt;span class="kwrd"&gt;if&lt;/span&gt; (SHA1Helper.SHA1Helper.CompareHashCodes(hash, request.FileHash))
            {
                status.Status = InitStatus.ExistsMatchingHash;
            }
            &lt;span class="kwrd"&gt;else&lt;/span&gt;
            {
                status.Status = InitStatus.ExistsNonMatchingHash;
            }
        }
    }
    &lt;span class="kwrd"&gt;else&lt;/span&gt;
    {
        status.Status = InitStatus.Ready;
    }

    InitUploadResponse response = &lt;span class="kwrd"&gt;new&lt;/span&gt; InitUploadResponse();
    response.Status = status;

    &lt;span class="kwrd"&gt;return&lt;/span&gt; response;
}

&lt;span class="kwrd"&gt;public&lt;/span&gt; GetUploadStatusResponse GetUploadStatus(GetUploadStatusRequest request)
{
    ... LicenseKey test goes here ...

    UploadStatusManager manager = UploadStatusManager.Instance;
    UploadStatusMessage message = &lt;span class="kwrd"&gt;new&lt;/span&gt; UploadStatusMessage();
    &lt;span class="kwrd"&gt;try&lt;/span&gt;
    {
        message.Status = manager[request.UploadID].Status;
        message.PercentComplete = manager[request.UploadID].PercentComplete;
        message.Message = manager[request.UploadID].Message;
    }
    &lt;span class="kwrd"&gt;catch&lt;/span&gt; (InvalidOperationException ex)
    {
        &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; FaultException&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(ex.Message, ex.Message);
    }

    GetUploadStatusResponse response = &lt;span class="kwrd"&gt;new&lt;/span&gt; GetUploadStatusResponse();
    response.StatusMessage = message;

    &lt;span class="kwrd"&gt;return&lt;/span&gt; response;
}

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; CancelUploadAsync(CancelUploadAsyncRequest request)
{
    ... LicenseKey test goes here ...

    &lt;span class="kwrd"&gt;try&lt;/span&gt;
    {
        UploadStatusManager.Instance[request.UploadID].CancelRequested = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
    }
    &lt;span class="kwrd"&gt;catch&lt;/span&gt; (InvalidOperationException ex)
    {
        &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; FaultException&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(ex.Message, ex.Message);
    }
}&lt;/pre&gt;
&lt;h3&gt;Support Classes&lt;/h3&gt;
&lt;p&gt;OK, so you may have noticed there are a couple of missing classes used on the above code.&amp;nbsp; The UploadStatusManager is used by the service to keep track of uploads.&amp;nbsp; Here's the code:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;internal&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; UploadStatusManagerItem
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; UploadStatus Status { get; set; }
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; PercentComplete { get; set; }
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Message { get; set; }
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; CancelRequested { get; set; }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; UploadStatusManagerItem()
    {
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.Status = UploadStatus.Idle;
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.CancelRequested = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
    }
}

&lt;span class="kwrd"&gt;internal&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; UploadStatusManager
{
    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; UploadStatusManager _manager = &lt;span class="kwrd"&gt;null&lt;/span&gt;;
    &lt;span class="kwrd"&gt;private&lt;/span&gt; Dictionary&amp;lt;Guid, UploadStatusManagerItem&amp;gt; _statusItems;

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; UploadStatusManager Instance
    {
        get
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (_manager == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            {
                _manager = &lt;span class="kwrd"&gt;new&lt;/span&gt; UploadStatusManager();
            }

            &lt;span class="kwrd"&gt;return&lt;/span&gt; _manager;
        }
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; UploadStatusManager()
    {
        _statusItems = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;Guid, UploadStatusManagerItem&amp;gt;();
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; UploadStatusManagerItem AddNewItem(Guid id)
    {
        var item = &lt;span class="kwrd"&gt;new&lt;/span&gt; UploadStatusManagerItem();
        _statusItems.Add(id, item);
        &lt;span class="kwrd"&gt;return&lt;/span&gt; item;
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; UploadStatusManagerItem &lt;span class="kwrd"&gt;this&lt;/span&gt;[Guid id]
    {
        get
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (!_status.Items.ContainsKey(id))
            {
                &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; InvalidOperationException(&lt;br /&gt;                                &lt;span class="str"&gt;"Item must be added before it is accessed."&lt;/span&gt;);
            }

            &lt;span class="kwrd"&gt;return&lt;/span&gt; _statusItems[id];
        }
    }
} &lt;/pre&gt;
&lt;p&gt;&lt;!-- .csharpcode, .csharpcode pre { 	font-size: small; 	color: black; 	font-family: consolas, "Courier New", courier, monospace; 	background-color: #ffffff; 	/*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt  { 	background-color: #f4f4f4; 	width: 100%; 	margin: 0em; } .csharpcode .lnum { color: #606060; } --&gt;&lt;/p&gt;
&lt;p&gt;You will also need to add a new project (so it can be shared with the client) called SHA1Helper, containing the following class:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; SHA1Helper
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] HashFile(Stream file)
    {
        var sha1 = &lt;span class="kwrd"&gt;new&lt;/span&gt; SHA1CryptoServiceProvider();
        &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] retval = sha1.ComputeHash(file);
        sha1.Clear();

        &lt;span class="kwrd"&gt;return&lt;/span&gt; retval;
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; CompareHashCodes(&lt;span class="kwrd"&gt;byte&lt;/span&gt;[] hash1, &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] hash2)
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (hash1.Length != hash2.Length)
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;
        }

        &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 0; i &amp;lt; hash1.Length; i++)
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (hash1[i] != hash2[i])
            {
                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;
            }
        }

        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;;
    }
}&lt;/pre&gt;
&lt;p&gt;&lt;!-- .csharpcode, .csharpcode pre { 	font-size: small; 	color: black; 	font-family: consolas, "Courier New", courier, monospace; 	background-color: #ffffff; 	/*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt  { 	background-color: #f4f4f4; 	width: 100%; 	margin: 0em; } .csharpcode .lnum { color: #606060; } --&gt;&lt;/p&gt;
&lt;h3&gt;Download Service Methods&lt;/h3&gt;
&lt;p&gt;The InitializeDownload method ensures that the requested file does exist, and returns the size and hash to the client so that it can prepare for the download.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;InitDownloadMessage message = &lt;span class="kwrd"&gt;new&lt;/span&gt; InitDownloadMessage();

&lt;span class="kwrd"&gt;string&lt;/span&gt; fileName = Path.Combine(Settings.Default.StreamStoragePath, request.FileName);
FileInfo fi = &lt;span class="kwrd"&gt;new&lt;/span&gt; FileInfo(fileName);

&lt;span class="kwrd"&gt;if&lt;/span&gt; (fi.Exists)
{
    message.FileName = Path.GetFileName(fi.Name);
    message.Length = fi.Length;

    &lt;span class="kwrd"&gt;if&lt;/span&gt; (request.CalculateHash)
    {
        &lt;span class="kwrd"&gt;using&lt;/span&gt; (var fs = fi.OpenRead())
        {
            message.FileHash = SHA1Helper.SHA1Helper.HashFile(fs);
        }
    }

    message.IsValidFile = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
}
&lt;span class="kwrd"&gt;else&lt;/span&gt;
{
    message.IsValidFile = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
}

InitDownloadResponse response = &lt;span class="kwrd"&gt;new&lt;/span&gt; InitDownloadResponse();
response.DownloadMessage = message;

&lt;span class="kwrd"&gt;return&lt;/span&gt; response;&lt;/pre&gt;
&lt;p&gt;&lt;!-- .csharpcode, .csharpcode pre { 	font-size: small; 	color: black; 	font-family: consolas, "Courier New", courier, monospace; 	background-color: #ffffff; 	/*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt  { 	background-color: #f4f4f4; 	width: 100%; 	margin: 0em; } .csharpcode .lnum { color: #606060; } --&gt;&lt;/p&gt;
&lt;h3&gt;And finally, the Streaming Classes&lt;/h3&gt;
&lt;p&gt;One more class, called StreamedFileTransferService, implementing the IStreamedFileTransferService interface. The two methods here (UploadStream and DownloadStream) include the same License Key checks as above.&amp;nbsp; The UploadStream method receives a Stream object (possibly with its Location already set to the length of an existing server-side file, to allow resume), and simply reads and appends data between the incoming (client, streamed) file and the local (server) file.&amp;nbsp; The DownloadStream method provides a Stream of the requested file (possibly with its Location set to a requested offset) to the client.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the code:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; UploadStreamResponse UploadStream(UploadStreamRequest request)
{
    &amp;hellip; LicenseKey test goes here &amp;hellip;

    UploadStatusManagerItem statusItem;
    &lt;span class="kwrd"&gt;try&lt;/span&gt;
    {
        statusItem = UploadStatusManager.Instance[request.UploadID];
    }
    &lt;span class="kwrd"&gt;catch&lt;/span&gt; (InvalidOperationException ex)
    {
        &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; FaultException&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(ex.Message, ex.Message);
    }

    statusItem.Message = &amp;ldquo;Uploading&amp;rdquo;;
    statusItem.Status = UploadStatus.Uploading;
    statusItem.PercentComplete = 0;

    &lt;span class="kwrd"&gt;bool&lt;/span&gt; result = &lt;span class="kwrd"&gt;false&lt;/span&gt;;

    &lt;span class="kwrd"&gt;string&lt;/span&gt; fileName = Path.Combine(Settings.Default.StreamStoragePath, request.FileName);
    &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] buffer = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;byte&lt;/span&gt;[65536];
    &lt;span class="kwrd"&gt;long&lt;/span&gt; totalread = 0L;
    &lt;span class="kwrd"&gt;int&lt;/span&gt; read;

    FileMode createMode = FileMode.CreateNew;
    &lt;span class="kwrd"&gt;switch&lt;/span&gt; (request.Mode)
    {
        &lt;span class="kwrd"&gt;case&lt;/span&gt; UploadMode.New:
            createMode = FileMode.CreateNew;
            &lt;span class="kwrd"&gt;break&lt;/span&gt;;

        &lt;span class="kwrd"&gt;case&lt;/span&gt; UploadMode.Overwrite:
            createMode = FileMode.Create;
            &lt;span class="kwrd"&gt;break&lt;/span&gt;;

        &lt;span class="kwrd"&gt;case&lt;/span&gt; UploadMode.Resume:
            createMode = FileMode.Append;
            &lt;span class="kwrd"&gt;break&lt;/span&gt;;
    }

    &lt;span class="kwrd"&gt;using&lt;/span&gt; (FileStream fs = &lt;span class="kwrd"&gt;new&lt;/span&gt; FileStream(fileName, createMode, FileAccess.Write, FileShare.None))
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (request.Mode == UploadMode.Resume)
        {
            fs.Seek(request.StartOffset, SeekOrigin.Begin);
        }

        &lt;span class="kwrd"&gt;while&lt;/span&gt; (((read = request.DataStream.Read(buffer, 0, buffer.Length)) &amp;gt; 0) &amp;amp;&amp;amp; !statusItem.CancelRequested)
        {
            fs.Write(buffer, 0, read);
            totalread += read;

            statusItem.PercentComplete = (&lt;span class="kwrd"&gt;int&lt;/span&gt;)((totalread * 100) / request.Length);
            statusItem.Message = &amp;ldquo;Uploading (&amp;ldquo; + statusItem.PercentComplete + &amp;ldquo;% complete)&amp;rdquo;;
        }

        fs.Flush();

        &lt;span class="kwrd"&gt;if&lt;/span&gt; (statusItem.CancelRequested)
        {
            statusItem.Message = &amp;ldquo;Upload Cancelled&amp;rdquo;;
            statusItem.Status = UploadStatus.Complete;
        }
        &lt;span class="kwrd"&gt;else&lt;/span&gt;
        {
            statusItem.PercentComplete = 100;
            statusItem.Status = UploadStatus.Complete;
            result = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
        }
    }

    request.DataStream.Close();

    UploadResultMessage message = &lt;span class="kwrd"&gt;new&lt;/span&gt; UploadResultMessage();

    &lt;span class="kwrd"&gt;if&lt;/span&gt; (!statusItem.CancelRequested)
    {
        statusItem.PercentComplete = 100;
        statusItem.Status = UploadStatus.CalculatingHash;
        statusItem.Message = &amp;ldquo;Calculating hash &lt;span class="kwrd"&gt;for&lt;/span&gt; Server file&amp;rdquo;;
        &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] hash;
        &lt;span class="kwrd"&gt;using&lt;/span&gt; (Stream s = File.OpenRead(fileName))
        {
            hash = SHA1Helper.SHA1Helper.HashFile(s);
        }

        result = SHA1Helper.SHA1Helper.CompareHashCodes(hash, request.FileHash);

        message.Result = result ? UploadResult.Success : UploadResult.Failure;
        message.Message = result ? &amp;ldquo;Upload Complete&amp;rdquo; : &amp;ldquo;Upload Failed &amp;ndash; Hash values &lt;span class="kwrd"&gt;do&lt;/span&gt; not match&amp;rdquo;;
    }
    &lt;span class="kwrd"&gt;else&lt;/span&gt;
    {
        message.Result = UploadResult.Failure;
        message.Message = &amp;ldquo;Upload Cancelled&amp;rdquo;;
    }

    UploadStreamResponse response = &lt;span class="kwrd"&gt;new&lt;/span&gt; UploadStreamResponse();
    response.ResultMessage = message;

    &lt;span class="kwrd"&gt;return&lt;/span&gt; response;
}

&lt;span class="kwrd"&gt;public&lt;/span&gt; DownloadStreamResponse DownloadStream(DownloadStreamRequest request)
{
    &amp;hellip; LicenseKey test goes here &amp;hellip;

    DownloadStreamResponse response = &lt;span class="kwrd"&gt;new&lt;/span&gt; DownloadStreamResponse();

    &lt;span class="kwrd"&gt;string&lt;/span&gt; fileName = Path.Combine(Settings.Default.StreamStoragePath, request.FileName);
    FileInfo fi = &lt;span class="kwrd"&gt;new&lt;/span&gt; FileInfo(fileName);

    &lt;span class="kwrd"&gt;if&lt;/span&gt; (fi.Exists)
    {
        response.FileName = request.FileName;
        response.Length = request.Length;
        response.FileHash = request.FileHash;
        response.DataStream = (Stream)fi.OpenRead();

        response.StartOffset = response.DataStream.Seek(request.StartOffset, SeekOrigin.Begin);

        &lt;span class="kwrd"&gt;return&lt;/span&gt; response;
    }

    &lt;span class="kwrd"&gt;const&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; fileReason = &amp;ldquo;Invalid file requested&amp;rdquo;;
    &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; FaultException&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(fileReason, fileReason);
}&lt;/pre&gt;
&lt;p&gt;&lt;!-- .csharpcode, .csharpcode pre { 	font-size: small; 	color: black; 	font-family: consolas, "Courier New", courier, monospace; 	background-color: #ffffff; 	/*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt  { 	background-color: #f4f4f4; 	width: 100%; 	margin: 0em; } .csharpcode .lnum { color: #606060; } --&gt;&lt;/p&gt;
&lt;h3&gt;Service Configuration&lt;/h3&gt;
&lt;p&gt;The final task to set up the service is to edit the App.config.&amp;nbsp; I won&amp;rsquo;t go into full details, but here&amp;rsquo;s the basic setup:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FileTransferService: NetTcp, Port 8000, Security Mode = None &lt;/li&gt;
&lt;li&gt;StreamedFileTransferService: NetTcp, Port 8000, Transfer Mode = Streamed, Security Mode = None &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&amp;rsquo;s probably a dangerous thing to set the Security Mode to None, but this was chosen in my case so that the client could access the server over the Internet without worrying about user credentials or certificates.&amp;nbsp; I do not recommend doing this in most situations, and it is up to the developer to choose a relevant security model for their specific application.&lt;/p&gt;
&lt;p&gt;After all that, you should be able to get your services up and running.&amp;nbsp; If you get a message about an AddressAccessDeniedException, check out &lt;a title="http://go.microsoft.com/fwlink/?LinkId=70353" href="http://go.microsoft.com/fwlink/?LinkId=70353"&gt;http://go.microsoft.com/fwlink/?LinkId=70353&lt;/a&gt; and open up the relevant ports.&lt;/p&gt;
&lt;p&gt;In the next article, I&amp;rsquo;ll move a bit quicker &amp;ndash; I&amp;rsquo;ve noticed the last couple of posts have been a bit on the long side.&amp;nbsp; To this end, I have created a repository over at &lt;a href="http://bitbucket.org/daggmano/wcffilestreamer/"&gt;http://bitbucket.org/daggmano/wcffilestreamer/&lt;/a&gt; so you can grab the source code as required.&lt;/p&gt;</description>
      <link>http://blog.darrenoster.com.au/post/Streaming-large-files-using-WCF-Part-2.aspx</link>
      <author>daggmano</author>
      <comments>http://blog.darrenoster.com.au/post/Streaming-large-files-using-WCF-Part-2.aspx#comment</comments>
      <guid>http://blog.darrenoster.com.au/post.aspx?id=1731438d-ec33-473a-8f00-69a02c7f3527</guid>
      <pubDate>Wed, 27 Jan 2010 02:08:00 +0500</pubDate>
      <category>Coding</category>
      <dc:publisher>daggmano</dc:publisher>
      <pingback:server>http://blog.darrenoster.com.au/pingback.axd</pingback:server>
      <pingback:target>http://blog.darrenoster.com.au/post.aspx?id=1731438d-ec33-473a-8f00-69a02c7f3527</pingback:target>
      <slash:comments>21554</slash:comments>
      <trackback:ping>http://blog.darrenoster.com.au/trackback.axd?id=1731438d-ec33-473a-8f00-69a02c7f3527</trackback:ping>
      <wfw:comment>http://blog.darrenoster.com.au/post/Streaming-large-files-using-WCF-Part-2.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.darrenoster.com.au/syndication.axd?post=1731438d-ec33-473a-8f00-69a02c7f3527</wfw:commentRss>
    </item>
    <item>
      <title>Streaming large files using WCF - Part 1</title>
      <description>&lt;p&gt;In this series of articles, I will walk through the process of creating a WCF service and client application which can be used to transfer large files (several gigabytes or more) between the client and the server.&amp;nbsp; The process will be broken down into the following stages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Creating the Server Application - 1 (this article) &lt;/li&gt;
&lt;li&gt;Creating the Server Application - 2 &lt;/li&gt;
&lt;li&gt;Creating the Client Application &lt;/li&gt;
&lt;li&gt;Creating an Installer for the Server &lt;/li&gt;
&lt;li&gt;Adding Extra Functionality &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Disclaimer&lt;/h3&gt;
&lt;p&gt;Before we begin, it&amp;rsquo;s probably a good idea to say that I am not an expert on WCF.&amp;nbsp; There are probably many other ways to implement this solution, and I do not claim that what is presented here is the best, or even one of the better, implementations.&amp;nbsp; That being said, it works, and that&amp;rsquo;s a good start. Please feel free to write a comment if you feel there are areas where the code needs improvement.&lt;/p&gt;
&lt;h3&gt;Creating the Server Application&lt;/h3&gt;
&lt;p&gt;I will be using Visual Studio 2008 and .NET 3.5 for this tutorial.&amp;nbsp; As is my preference, I&amp;rsquo;ll start by creating a new Blank Visual Studio Solution, called WCFFileStreamer.&amp;nbsp; In here, add a new WCF Service Library, named WCFFileStreamerService.&lt;/p&gt;
&lt;h3&gt;Shared Types&lt;/h3&gt;
&lt;p&gt;By default, the WCF Service Library includes an Interface called IService1 to define the Service and Data Contracts.&amp;nbsp; The &amp;lsquo;correct&amp;rsquo; method of sharing these types between the client and server is to import a service reference to the client, but I have run into problems with this on previous projects so will manually configure this interaction.&amp;nbsp; A couple advantages of this are that it enables more control over the interactions, and that it gives us a better feel for what happens &amp;lsquo;under the covers&amp;rsquo; in WCF.&lt;/p&gt;
&lt;p&gt;Add a new project to the solution, in this case just a Class Library named WCFFileStreamerTypes.&amp;nbsp; There will be a number of enums, classes and interfaces to create, but they&amp;rsquo;re all quite small and have no logic in them, so feel free to either create one file per enum / class / interface, or just throw everything in one file.&amp;nbsp; You&amp;rsquo;ll also need to add references to System.ServiceModel and System.Runtime.Serialization.&amp;nbsp; Here are the enums you&amp;rsquo;ll need:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;[DataContract(Namespace = &lt;span class="str"&gt;"http://schemas.my.service.com/2009/07/filestreamer/"&lt;/span&gt;)]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;enum&lt;/span&gt; UploadStatus : &lt;span class="kwrd"&gt;int&lt;/span&gt;
{
    [EnumMember] Complete = 0,
    [EnumMember] Uploading = 1,
    [EnumMember] CalculatingHash = 2,
    [EnumMember] Idle = 3
}&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;[DataContract(Namespace = &lt;span class="str"&gt;"http://schemas.my.service.com/2009/07/filestreamer/"&lt;/span&gt;)]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;enum&lt;/span&gt; InitStatus : &lt;span class="kwrd"&gt;int&lt;/span&gt;
{
    [EnumMember] Ready = 0,
    [EnumMember] ExistsAndResumable = 1,
    [EnumMember] ExistsMatchingHash = 2,
    [EnumMember] ExistsNonMatchingHash = 3
}&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;[DataContract(Namespace = &lt;span class="str"&gt;"http://schemas.my.service.com/2009/07/filestreamer/"&lt;/span&gt;)]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;enum&lt;/span&gt; UploadMode : &lt;span class="kwrd"&gt;int&lt;/span&gt;
{
    [EnumMember] New = 0,
    [EnumMember] Overwrite = 1,
    [EnumMember] Resume = 2
}&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;[DataContract(Namespace = &lt;span class="str"&gt;"http://schemas.my.service.com/2009/07/filestreamer/"&lt;/span&gt;)]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;enum&lt;/span&gt; UploadResult : &lt;span class="kwrd"&gt;int&lt;/span&gt;
{
    [EnumMember] Success = 0,
    [EnumMember] Failure = 1
}&lt;/pre&gt;
&lt;p&gt;The following classes will be required as Data Contracts:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;[DataContract(Namespace = &lt;span class="str"&gt;"http://schemas.my.service.com/2009/07/filestreamer/"&lt;/span&gt;)]
[KnownType(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(InitStatus))]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; InitializeStatus
{
    [DataMember(IsRequired = &lt;span class="kwrd"&gt;true&lt;/span&gt;)] &lt;span class="kwrd"&gt;public&lt;/span&gt; InitStatus Status { get; set; }
    [DataMember(IsRequired = &lt;span class="kwrd"&gt;true&lt;/span&gt;)] &lt;span class="kwrd"&gt;public&lt;/span&gt; Guid UploadID { get; set; }
    [DataMember(IsRequired = &lt;span class="kwrd"&gt;true&lt;/span&gt;)] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;long&lt;/span&gt; Length { get; set; }
    [DataMember(IsRequired = &lt;span class="kwrd"&gt;true&lt;/span&gt;)] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;long&lt;/span&gt; ServerLength { get; set; }
}&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;[DataContract(Namespace = &lt;span class="str"&gt;"http://schemas.my.service.com/2009/07/filestreamer/"&lt;/span&gt;)]
[KnownType(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(UploadResult))]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; UploadResultMessage
{
    [DataMember(IsRequired = &lt;span class="kwrd"&gt;true&lt;/span&gt;)] &lt;span class="kwrd"&gt;public&lt;/span&gt; UploadResult Result { get; set; }
    [DataMember(IsRequired = &lt;span class="kwrd"&gt;true&lt;/span&gt;)] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Message { get; set; }
}&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;[DataContract(Namespace = &lt;span class="str"&gt;"http://schemas.my.service.com/2009/07/filestreamer/"&lt;/span&gt;)]
[KnownType(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(UploadStatus))]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; UploadStatusMessage
{
    [DataMember(IsRequired = &lt;span class="kwrd"&gt;true&lt;/span&gt;)] &lt;span class="kwrd"&gt;public&lt;/span&gt; UploadStatus Status { get; set; }
    [DataMember(IsRequired = &lt;span class="kwrd"&gt;true&lt;/span&gt;)] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; PercentComplete { get; set; }
    [DataMember(IsRequired = &lt;span class="kwrd"&gt;true&lt;/span&gt;)] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Message { get; set; }
}&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;[DataContract(Namespace = &lt;span class="str"&gt;"http://schemas.my.service.com/2009/07/filestreamer/"&lt;/span&gt;)]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; InitDownloadMessage
{
    [DataMember(IsRequired = &lt;span class="kwrd"&gt;true&lt;/span&gt;)] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; IsValidFile { get; set; }
    [DataMember(IsRequired = &lt;span class="kwrd"&gt;true&lt;/span&gt;)] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; FileName { get; set; }
    [DataMember(IsRequired = &lt;span class="kwrd"&gt;true&lt;/span&gt;)] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;long&lt;/span&gt; Length { get; set; }
    [DataMember(IsRequired = &lt;span class="kwrd"&gt;true&lt;/span&gt;)] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] FileHash { get; set; }
}&lt;/pre&gt;
&lt;p&gt;Add the following Message Contracts:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;[MessageContract(IsWrapped = &lt;span class="kwrd"&gt;false&lt;/span&gt;)]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; InitUploadRequest
{
    [MessageHeader(MustUnderstand = &lt;span class="kwrd"&gt;true&lt;/span&gt;)] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; LicenseKey { get; set; }
    [MessageBodyMember] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; FileName { get; set; }
    [MessageBodyMember] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;long&lt;/span&gt; Length { get; set; }
    [MessageBodyMember] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] FileHash { get; set; }
}&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;[MessageContract(IsWrapped = &lt;span class="kwrd"&gt;false&lt;/span&gt;)]
[KnownType(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(InitializeStatus))]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; InitUploadResponse
{
    [MessageBodyMember] &lt;span class="kwrd"&gt;public&lt;/span&gt; InitializeStatus Status { get; set; }
}&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;[MessageContract(IsWrapped = &lt;span class="kwrd"&gt;false&lt;/span&gt;)]
[KnownType(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(UploadMode))]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; UploadStreamRequest
{
    [MessageHeader(MustUnderstand = &lt;span class="kwrd"&gt;true&lt;/span&gt;)] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; LicenseKey { get; set; }
    [MessageHeader] &lt;span class="kwrd"&gt;public&lt;/span&gt; Guid UploadID { get; set; }
    [MessageHeader] &lt;span class="kwrd"&gt;public&lt;/span&gt; UploadMode Mode { get; set; }
    [MessageHeader] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; FileName { get; set; }
    [MessageHeader] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;long&lt;/span&gt; Length { get; set; }
    [MessageHeader] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;long&lt;/span&gt; StartOffset { get; set; }
    [MessageHeader] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] FileHash { get; set; }
    [MessageBodyMember] &lt;span class="kwrd"&gt;public&lt;/span&gt; Stream DataStream { get; set; }
}&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;[MessageContract(IsWrapped = &lt;span class="kwrd"&gt;false&lt;/span&gt;)]
[KnownType(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(UploadResultMessage))]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; UploadStreamResponse
{
    [MessageHeader] &lt;span class="kwrd"&gt;public&lt;/span&gt; UploadResultMessage ResultMessage { get; set; }
}&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;[MessageContract(IsWrapped = &lt;span class="kwrd"&gt;false&lt;/span&gt;)]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; GetUploadStatusRequest
{
    [MessageHeader(MustUnderstand = &lt;span class="kwrd"&gt;true&lt;/span&gt;)] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; LicenseKey { get; set; }
    [MessageBodyMember] &lt;span class="kwrd"&gt;public&lt;/span&gt; Guid UploadID { get; set; }
}&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;[MessageContract(IsWrapped = &lt;span class="kwrd"&gt;false&lt;/span&gt;)]
[KnownType(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(UploadStatusMessage))]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; GetUploadStatusResponse
{
    [MessageBodyMember] &lt;span class="kwrd"&gt;public&lt;/span&gt; UploadStatusMessage StatusMessage { get; set; }
}&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;[MessageContract(IsWrapped = &lt;span class="kwrd"&gt;false&lt;/span&gt;)]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CancelUploadAsyncRequest
{
    [MessageHeader(MustUnderstand = &lt;span class="kwrd"&gt;true&lt;/span&gt;)] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; LicenseKey { get; set; }
    [MessageBodyMember] &lt;span class="kwrd"&gt;public&lt;/span&gt; Guid UploadID { get; set; }
}&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;[MessageContract(IsWrapped = &lt;span class="kwrd"&gt;false&lt;/span&gt;)]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; InitDownloadRequest
{
    [MessageHeader(MustUnderstand = &lt;span class="kwrd"&gt;true&lt;/span&gt;)] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; LicenseKey { get; set; }
    [MessageBodyMember] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; FileName { get; set; }
    [MessageBodyMember] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; CalculateHash { get; set; }
}&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;[MessageContract(IsWrapped = &lt;span class="kwrd"&gt;false&lt;/span&gt;)]
[KnownType(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(InitDownloadMessage))]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; InitDownloadResponse
{
    [MessageBodyMember] &lt;span class="kwrd"&gt;public&lt;/span&gt; InitDownloadMessage DownloadMessage { get; set; }
}&lt;/pre&gt;
&lt;p&gt;&lt;!-- .csharpcode, .csharpcode pre { 	font-size: small; 	color: black; 	font-family: consolas, "Courier New", courier, monospace; 	background-color: #ffffff; 	/*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt  { 	background-color: #f4f4f4; 	width: 100%; 	margin: 0em; } .csharpcode .lnum { color: #606060; } --&gt;&lt;/p&gt;
&lt;pre class="csharpcode"&gt;[MessageContract(IsWrapped = &lt;span class="kwrd"&gt;false&lt;/span&gt;)]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; DownloadStreamRequest
{
    [MessageHeader(MustUnderstand = &lt;span class="kwrd"&gt;true&lt;/span&gt;)] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; LicenseKey { get; set; }
    [MessageHeader] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; FileName { get; set; }
    [MessageHeader] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;long&lt;/span&gt; Length { get; set; }
    [MessageHeader] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;long&lt;/span&gt; StartOffset { get; set; }
    [MessageHeader] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] FileHash { get; set; }
}&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;[MessageContract(IsWrapped = &lt;span class="kwrd"&gt;false&lt;/span&gt;)]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; DownloadStreamResponse
{
    [MessageHeader] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; FileName { get; set; }
    [MessageHeader] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;long&lt;/span&gt; Length { get; set; }
    [MessageHeader] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;long&lt;/span&gt; StartOffset { get; set; }
    [MessageHeader] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] FileHash { get; set; }
    [MessageBodyMember] &lt;span class="kwrd"&gt;public&lt;/span&gt; Stream DataStream { get; set; }
}&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;[MessageContract(IsWrapped = &lt;span class="kwrd"&gt;false&lt;/span&gt;)]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; GetFreeSpaceRequest
{
    [MessageHeader(MustUnderstand = &lt;span class="kwrd"&gt;true&lt;/span&gt;)] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; LicenseKey { get; set; }
}&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;[MessageContract(IsWrapped = &lt;span class="kwrd"&gt;false&lt;/span&gt;)]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; GetFreeSpaceResponse
{
    [MessageBodyMember] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;long&lt;/span&gt; FreeSpace { get; set; }
}&lt;/pre&gt;
&lt;p&gt;A couple of things are worth noticing in the above Message Contracts.&amp;nbsp; The first thing is that every request includes a LicenseKey string in the Header.&amp;nbsp; This is a fairly easy way to provide some security to our service.&amp;nbsp; You can either hard code a word or phrase into your service and client (as we will do here), or you could use some other method.&lt;/p&gt;
&lt;p&gt;The second thing to notice is the liberal use of MessageHeader parameters in the UploadStreamRequest / UploadStreamResponse contracts.&amp;nbsp; This reason for this will become clear later.&lt;/p&gt;
&lt;p&gt;Finally we can create the Service Contracts.&amp;nbsp; Note that there are two interfaces specified for the server.&amp;nbsp; I will talk about the reasons for this more in the next article.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;[ServiceContract(Name = &lt;span class="str"&gt;"StreamedFileTransferService"&lt;/span&gt;,&lt;br /&gt;                 Namespace = &lt;span class="str"&gt;"http://www.my.service.com/2009/07/filestreamer/"&lt;/span&gt;)]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; IStreamedFileTransferService
{
    [OperationContract]
    [FaultContract(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt;))]
    UploadStreamResponse UploadStream(UploadStreamRequest request);

    [OperationContract]
    [FaultContract(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt;))]
    DownloadStreamResponse DownloadStream(DownloadStreamRequest request);
}&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;[ServiceContract(Name = &lt;span class="str"&gt;"FileTransferService"&lt;/span&gt;,&lt;br /&gt;                 Namespace = &lt;span class="str"&gt;"http://www.my.service.com/2009/07/filestreamer/"&lt;/span&gt;)]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; IFileTransferService
{
    [OperationContract]
    [FaultContract(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt;))]
    InitUploadResponse InitializeUpload(InitUploadRequest request);

    [OperationContract]
    [FaultContract(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt;))]
    GetUploadStatusResponse GetUploadStatus(GetUploadStatusRequest request);

    [OperationContract]
    [FaultContract(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt;))]
    &lt;span class="kwrd"&gt;void&lt;/span&gt; CancelUploadAsync(CancelUploadAsyncRequest request);

    [OperationContract]
    [FaultContract(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt;))]
    InitDownloadResponse InitializeDownload(InitDownloadRequest request);

    [OperationContract]
    [FaultContract(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt;))]
    GetFreeSpaceResponse GetFreeSpace(GetFreeSpaceRequest request);
}&lt;/pre&gt;
&lt;p&gt;We will also provide a couple of interfaces for the client side, including asynchronous pattern calls (I told you we'd be getting dirty with manual configuration).&amp;nbsp; Because the code for this gets pretty long and repetitive, I&amp;rsquo;ll just show the first few definitions here.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;[ServiceContract(Name = &lt;span class="str"&gt;"StreamedFileTransferClient"&lt;/span&gt;,&lt;br /&gt;                 Namespace = &lt;span class="str"&gt;"http://www.my.service.com/2009/07/filestreamer/"&lt;/span&gt;)]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; IStreamedFileTransferClient
{
    [OperationContract(
        Action = &lt;span class="str"&gt;"http://www.my.service.com/2009/07/filestreamer/_&lt;br /&gt;                                  StreamedFileTransferService/UploadStream"&lt;/span&gt;,
        ReplyAction = &lt;span class="str"&gt;"http://www.my.service.com/2009/07/filestreamer/_&lt;br /&gt;                                  StreamedFileTransferService/UploadStreamResponse"&lt;/span&gt;)]
    [FaultContract(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt;))]
    UploadStreamResponse UploadStream(UploadStreamRequest request);

    [OperationContract(AsyncPattern = &lt;span class="kwrd"&gt;true&lt;/span&gt;,
        Action = &lt;span class="str"&gt;"http://www.my.service.com/2009/07/filestreamer/_&lt;br /&gt;                                  StreamedFileTransferService/UploadStream"&lt;/span&gt;,
        ReplyAction = &lt;span class="str"&gt;"http://www.my.service.com/2009/07/filestreamer/_&lt;br /&gt;                                  StreamedFileTransferService/UploadStreamResponse"&lt;/span&gt;)]
    IAsyncResult BeginUploadStream(UploadStreamRequest request, AsyncCallback callback,&lt;br /&gt;                                   &lt;span class="kwrd"&gt;object&lt;/span&gt; asyncState);

    UploadStreamResponse EndUploadStream(IAsyncResult result);

    [OperationContract(
        Action = &lt;span class="str"&gt;"http://www.my.service.com/2009/07/filestreamer/_&lt;br /&gt;                                  StreamedFileTransferService/DownloadStream"&lt;/span&gt;,
        ReplyAction = &lt;span class="str"&gt;"http://www.my.service.com/2009/07/filestreamer/_&lt;br /&gt;                                  StreamedFileTransferService/DownloadStreamResponse"&lt;/span&gt;)]
    [FaultContract(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt;))]
    DownloadStreamResponse DownloadStream(DownloadStreamRequest request);

    [OperationContract(AsyncPattern = &lt;span class="kwrd"&gt;true&lt;/span&gt;,
        Action = &lt;span class="str"&gt;"http://www.my.service.com/2009/07/filestreamer/_&lt;br /&gt;                                  StreamedFileTransferService/DownloadStream"&lt;/span&gt;,
        ReplyAction = &lt;span class="str"&gt;"http://www.my.service.com/2009/07/filestreamer/_&lt;br /&gt;                                  StreamedFileTransferService/DownloadStreamResponse"&lt;/span&gt;)]
    IAsyncResult BeginDownloadStream(DownloadStreamRequest request, AsyncCallback callback,&lt;br /&gt;                                     &lt;span class="kwrd"&gt;object&lt;/span&gt; asyncState);

    DownloadStreamResponse EndDownloadStream(IAsyncResult result);
}&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;[ServiceContract(Name = &lt;span class="str"&gt;"FileTransferClient"&lt;/span&gt;,&lt;br /&gt;                 Namespace = &lt;span class="str"&gt;"http://www.my.service.com/2009/07/filestreamer/"&lt;/span&gt;)]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; IFileTransferClient
{
    [OperationContract(
        Action = &lt;span class="str"&gt;"http://www.my.service.com/2009/07/filestreamer/_&lt;br /&gt;                                  FileTransferService/InitializeUpload"&lt;/span&gt;,
        ReplyAction = &lt;span class="str"&gt;"http://www.my.service.com/2009/07/filestreamer/_&lt;br /&gt;                                  FileTransferService/InitializeUploadResponse"&lt;/span&gt;)]
    [FaultContract(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt;))]
    InitUploadResponse InitializeUpload(InitUploadRequest request);

    [OperationContract(AsyncPattern = &lt;span class="kwrd"&gt;true&lt;/span&gt;,
        Action = &lt;span class="str"&gt;"http://www.my.service.com/2009/07/filestreamer/_&lt;br /&gt;                                  FileTransferService/InitializeUpload"&lt;/span&gt;,
        ReplyAction = &lt;span class="str"&gt;"http://www.my.service.com/2009/07/filestreamer/_&lt;br /&gt;                                  FileTransferService/InitializeUploadResponse"&lt;/span&gt;)]
    IAsyncResult BeginInitializeUpload(InitUploadRequest request, AsyncCallback callback,&lt;br /&gt;                                       &lt;span class="kwrd"&gt;object&lt;/span&gt; asyncState);

    InitUploadResponse EndInitializeUpload(IAsyncResult result);

    &lt;span class="rem"&gt;// ... Same pattern for all contracts except the following:&lt;/span&gt;

    [OperationContract(
        Action = &lt;span class="str"&gt;"http://www.my.service.com/2009/07/filestreamer/_&lt;br /&gt;                                  FileTransferService/CancelUpload"&lt;/span&gt;,
        ReplyAction = &lt;span class="str"&gt;"http://www.my.service.com/2009/07/filestreamer/_&lt;br /&gt;                                  FileTransferService/CancelUploadResponse"&lt;/span&gt;)]
    [FaultContract(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt;))]
    &lt;span class="kwrd"&gt;void&lt;/span&gt; CancelUploadAsync(CancelUploadAsyncRequest request);
}&lt;/pre&gt;
&lt;p&gt;Note that the &amp;lsquo;_&amp;rsquo; line continuation characters are only to allow the code to fit into my blog &amp;ndash; these lines should be on a single line.&lt;/p&gt;
&lt;p&gt;That should do for now.&amp;nbsp; Make sure the solution builds (it won't do anything yet), and check out the next article to get the service up and running.&lt;/p&gt;</description>
      <link>http://blog.darrenoster.com.au/post/Streaming-large-files-using-WCF-Part-1.aspx</link>
      <author>daggmano</author>
      <comments>http://blog.darrenoster.com.au/post/Streaming-large-files-using-WCF-Part-1.aspx#comment</comments>
      <guid>http://blog.darrenoster.com.au/post.aspx?id=b27f7e11-8b5b-4b8c-8583-3f25bedae892</guid>
      <pubDate>Wed, 20 Jan 2010 12:14:00 +0500</pubDate>
      <category>Coding</category>
      <dc:publisher>daggmano</dc:publisher>
      <pingback:server>http://blog.darrenoster.com.au/pingback.axd</pingback:server>
      <pingback:target>http://blog.darrenoster.com.au/post.aspx?id=b27f7e11-8b5b-4b8c-8583-3f25bedae892</pingback:target>
      <slash:comments>13632</slash:comments>
      <trackback:ping>http://blog.darrenoster.com.au/trackback.axd?id=b27f7e11-8b5b-4b8c-8583-3f25bedae892</trackback:ping>
      <wfw:comment>http://blog.darrenoster.com.au/post/Streaming-large-files-using-WCF-Part-1.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.darrenoster.com.au/syndication.axd?post=b27f7e11-8b5b-4b8c-8583-3f25bedae892</wfw:commentRss>
    </item>
    <item>
      <title>The argument against Test Driven Development</title>
      <description>&lt;p&gt;It seems that every time I listen to a software development podcast (which is often), somebody is talking up the benefits of Test Driven Development (TDD).&amp;#160; TDD does indeed have many advantages.&amp;#160; It focuses our efforts by ensuring that the code we write is written for a reason, i.e. to make a test, which has been derived from the requirements specification, pass.&amp;#160; This is in keeping with the YAGNI (You Ain’t Gonna Need It) principle.&lt;/p&gt;  &lt;p&gt;TDD also allows a safety net for refactoring, to ensure that, after a refactoring, the code is no more broken than it was before the refactoring.&amp;#160; TDD is also likely to lead to ‘better’ code - more modular, cleaner, with less unwanted dependencies between classes.&amp;#160; And all of these are worthy goals, and perhaps are reasons in themselves for adopting (at least partially) the TDD process.&lt;/p&gt;  &lt;p&gt;Where I take exception, however, is that it is somehow implied (and even stated) that TDD cannot help but ensure that the code we write will be ‘correct’.&amp;#160; &lt;a href="http://en.wikipedia.org/wiki/Test_driven_development#Benefits"&gt;Wikipedia states&lt;/a&gt; that, “Test-driven development offers more that just simple validation of correctness”, which would indicate that TDD does indeed offer validation of correctness.&amp;#160; But it doesn’t.&amp;#160; Let me illustrate the point.&lt;/p&gt;  &lt;p&gt;I need a method that will return the square of a given integer.&amp;#160; That seems simple, so I write a unit test.&lt;/p&gt;  &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;[Test]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; TestThatTwoSquaredIsFour()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    Assert.IsTrue(Square(2) == 4);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Note that this is psuedo-code, but you get the idea.&amp;#160; Okay, let’s have a crack at writing the method to satisfy this test.&amp;#160; Again, &lt;a href="http://en.wikipedia.org/wiki/Test_driven_development#3._Write_some_code"&gt;Wikipedia gives us some guidance&lt;/a&gt;. &lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The next step is to write some code that will cause the test to pass... It is important that the code written is &lt;em&gt;only&lt;/em&gt; designed to pass the test...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, with this in mind, here is my code.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; Square(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; n)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; 4;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;This is the simplest code that I can write that will pass the test.&amp;#160; And the test will pass.&amp;#160; Since this is the case, we obviously have not specified the requirements clearly enough (through tests), so we'll add another test.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;[Test]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; TestThatThreeSquaredIsNine()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    Assert.IsTrue(Square(3) == 9);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Our code now fails the second test, so let’s ‘fix’ the code in the simplest way possible.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; Square(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; n)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (n == 2)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; 4;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; 9;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Run the tests again, and we have a nice green lawn.&amp;#160; But incorrect code.&amp;#160; We can go on adding more and more specific test cases, modify our method under test to pass those tests by using if statements or switch statements, and still have incorrect code.&lt;/p&gt;

&lt;p&gt;How about adding a randomization aspect to the test, such as the following?&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;[Test]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; TestThatSquareOfRandomNumberIsCorrect()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; n = Random(1000);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; result = n * n;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    Assert.IsTrue(Square(n) == result);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;We now have a test that will (probably) force us to write a method which calculates a result rather than selecting from a limited range of options, but there are two problems: first, the test is overly complicated, and second, we have already written the required method inside the test!&lt;/p&gt;

&lt;p&gt;So here’s the takeaway: Test Driven Development is a useful methodology which encourages the developer to develop only what is needed, in a testable and maintainable way.&amp;#160; However, it is important to realise that TDD does NOT mean that the produced code is correct in all cases - &lt;em&gt;it is only correct in those cases for which specific tests exist&lt;/em&gt;.&amp;#160; As far as TDD is concerned, the code can fail in every other imaginable case.&amp;#160; So keep using your brain as you develop.&amp;#160; Allow TDD to do those things at which it excels, but don't expect it to have the &lt;a href="http://en.wikipedia.org/wiki/Midas_touch"&gt;Midas Touch&lt;/a&gt; - or you may very well fail.&lt;/p&gt;</description>
      <link>http://blog.darrenoster.com.au/post/The-argument-against-Test-Driven-Development.aspx</link>
      <author>daggmano</author>
      <comments>http://blog.darrenoster.com.au/post/The-argument-against-Test-Driven-Development.aspx#comment</comments>
      <guid>http://blog.darrenoster.com.au/post.aspx?id=0c2b72c9-83c5-4c60-8101-41613c86ead4</guid>
      <pubDate>Thu, 08 Oct 2009 07:45:00 +0500</pubDate>
      <category>Other Development</category>
      <dc:publisher>daggmano</dc:publisher>
      <pingback:server>http://blog.darrenoster.com.au/pingback.axd</pingback:server>
      <pingback:target>http://blog.darrenoster.com.au/post.aspx?id=0c2b72c9-83c5-4c60-8101-41613c86ead4</pingback:target>
      <slash:comments>7200</slash:comments>
      <trackback:ping>http://blog.darrenoster.com.au/trackback.axd?id=0c2b72c9-83c5-4c60-8101-41613c86ead4</trackback:ping>
      <wfw:comment>http://blog.darrenoster.com.au/post/The-argument-against-Test-Driven-Development.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.darrenoster.com.au/syndication.axd?post=0c2b72c9-83c5-4c60-8101-41613c86ead4</wfw:commentRss>
    </item>
    <item>
      <title>Loading forms dynamically in WPF</title>
      <description>&lt;p&gt;A friend of mine who is learning WPF recently asked me how to load forms dynamically into the panes of a tab control. Being the helpful sort I am, I wrote up a quick app that demonstrates this.&lt;/p&gt;  &lt;p&gt;Essentially, the idea is to create the forms as UserControls, and then load these at runtime into the host control (either a TabItem or some other Content or Item control such as a Grid). Remember that for a Content Control, you would set mycontrol.Content to the new form, while an Items control can contain multiple children, so to replace the content with a form you would call mycontrol.Children.Clear(), followed by mycontrol.Children.Add(newform).&lt;/p&gt;  &lt;p&gt;The demo app is &lt;a href="http://cid-6bd010a81465a625.skydrive.live.com/self.aspx/.Public/DynamicFormsDemo.zip"&gt;available here&lt;/a&gt;.&lt;/p&gt;</description>
      <link>http://blog.darrenoster.com.au/post/Loading-forms-dynamically-in-WPF.aspx</link>
      <author>daggmano</author>
      <comments>http://blog.darrenoster.com.au/post/Loading-forms-dynamically-in-WPF.aspx#comment</comments>
      <guid>http://blog.darrenoster.com.au/post.aspx?id=2ba000c8-7252-40a4-bd19-5d9f3360b57d</guid>
      <pubDate>Wed, 07 Oct 2009 09:30:00 +0500</pubDate>
      <category>Coding</category>
      <dc:publisher>daggmano</dc:publisher>
      <pingback:server>http://blog.darrenoster.com.au/pingback.axd</pingback:server>
      <pingback:target>http://blog.darrenoster.com.au/post.aspx?id=2ba000c8-7252-40a4-bd19-5d9f3360b57d</pingback:target>
      <slash:comments>11879</slash:comments>
      <trackback:ping>http://blog.darrenoster.com.au/trackback.axd?id=2ba000c8-7252-40a4-bd19-5d9f3360b57d</trackback:ping>
      <wfw:comment>http://blog.darrenoster.com.au/post/Loading-forms-dynamically-in-WPF.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.darrenoster.com.au/syndication.axd?post=2ba000c8-7252-40a4-bd19-5d9f3360b57d</wfw:commentRss>
    </item>
    <item>
      <title>Japan - The Last Day</title>
      <description>&lt;p&gt;I managed to find some free internet access in the departure lounge, so decided to make use of it.&amp;nbsp; I left Panasonic today at 3pm local time, and caught the train back to the hotel to pick up my baggage.&amp;nbsp; My timing was impeccable, as the airport bus was only a few short minutes from leaving as I got to the stop.&amp;nbsp; The 70-odd minute ride to the airport was quiet, and gave me a chance to try to find a word to sum up my impressions of Japan.&amp;nbsp; I think I found it - &amp;ldquo;drab&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Now, this may be peculiar to this part of Japan (Osaka - Kyoto), but everything feels just a little gray, perhaps grimy, and yet remarkably sterile.&amp;nbsp; There is very little litter, and I never saw any graffiti at all.&amp;nbsp; Perhaps the youth of Japan are instilled with a little more respect for others and for authority here, and certainly crime is lower in Japan than back at home.&amp;nbsp; For all that, it still feels a little lifeless.&lt;/p&gt;
&lt;p&gt;Approaching Kansai Airport near Osaka, I realised something I hadn't picked up when I arrived - Kansai Aiport is on a man-made island (check it out on &lt;a href="http://maps.google.com.au/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=kansai+airport+osaka&amp;amp;sll=10.833306,139.306641&amp;amp;sspn=60.600977,76.992187&amp;amp;ie=UTF8&amp;amp;cd=1&amp;amp;ll=34.418098,135.264187&amp;amp;spn=0.100684,0.150375&amp;amp;z=13"&gt;Google Maps&lt;/a&gt;), and is reached by a bridge about 3km long!&lt;/p&gt;
&lt;p&gt;I arrived at the airport about 90 minutes before check in opened, and so sat down for a while before taking a walk to find some sustenance.&amp;nbsp;&amp;nbsp; Much to my delight, I found ... a Starbucks!!&amp;nbsp; Real coffee!!&amp;nbsp; I was so thrilled at the prospect that it was some minutes before I realised that I had lost my mobile phone.&amp;nbsp; It must have slipped out of my pocket while I was sitting down, two floors above.&amp;nbsp; Retracing my steps brought no joy - it was gone.&amp;nbsp; So, off to the info counter.&amp;nbsp; Had a phone been handed in?&amp;nbsp; &amp;ldquo;Oh, please wait while I get paperwork&amp;rdquo;.&amp;nbsp; It wasn't until about a minute later that she pulls out my phone and says, &amp;ldquo;Is this yours?&amp;rdquo;&amp;nbsp; That phone may not be much more than a hill of beans, but it was my hill, and those were my beans!!&lt;/p&gt;
&lt;p&gt;Anyway, I am looking forward to getting back to Oz and seeing my (in some cases sick) kids again.&amp;nbsp; It&amp;rsquo;s been a good trip, and one that has given me some good memories, but for now, I&amp;rsquo;m glad it&amp;rsquo;s over.&lt;/p&gt;</description>
      <link>http://blog.darrenoster.com.au/post/Japan-The-Last-Day.aspx</link>
      <author>daggmano</author>
      <comments>http://blog.darrenoster.com.au/post/Japan-The-Last-Day.aspx#comment</comments>
      <guid>http://blog.darrenoster.com.au/post.aspx?id=ca59caed-2114-4c9c-b280-9839763ab066</guid>
      <pubDate>Sat, 12 Sep 2009 18:13:00 +0500</pubDate>
      <category>Miscellaneous</category>
      <dc:publisher>daggmano</dc:publisher>
      <pingback:server>http://blog.darrenoster.com.au/pingback.axd</pingback:server>
      <pingback:target>http://blog.darrenoster.com.au/post.aspx?id=ca59caed-2114-4c9c-b280-9839763ab066</pingback:target>
      <slash:comments>8152</slash:comments>
      <trackback:ping>http://blog.darrenoster.com.au/trackback.axd?id=ca59caed-2114-4c9c-b280-9839763ab066</trackback:ping>
      <wfw:comment>http://blog.darrenoster.com.au/post/Japan-The-Last-Day.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.darrenoster.com.au/syndication.axd?post=ca59caed-2114-4c9c-b280-9839763ab066</wfw:commentRss>
    </item>
  </channel>
</rss>