<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ronnie Holm&#039;s blog</title>
	<atom:link href="http://www.bugfree.dk/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.bugfree.dk/blog</link>
	<description></description>
	<lastBuildDate>Sat, 09 Mar 2013 23:05:43 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4</generator>
		<item>
		<title>Strongly typed SharePoint list operations using the repository pattern in F#</title>
		<link>http://www.bugfree.dk/blog/2012/12/24/strongly-typed-sharepoint-list-operations-using-the-repository-pattern-in-f/</link>
		<comments>http://www.bugfree.dk/blog/2012/12/24/strongly-typed-sharepoint-list-operations-using-the-repository-pattern-in-f/#comments</comments>
		<pubDate>Mon, 24 Dec 2012 13:22:47 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[F#]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[.Net]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1114</guid>
		<description><![CDATA[This post is part of series: Part 4 &#8211; Strongly typed SharePoint list operations using the repository pattern in F# Part 3 &#8211; Bringing together repository and tree structure in business layer Part 2 &#8211; Creating and working with a custom tree data structure in C# Part 1 &#8211; Strongly typed SharePoint list operations using [...]]]></description>
			<content:encoded><![CDATA[<p>
This post is part of series:
</p>
<p>
Part 4 &#8211; Strongly typed SharePoint list operations using the repository pattern in F#<br />
Part 3 &#8211; <a href="http://www.bugfree.dk/blog/2012/12/06/bringing-together-repository-and-tree-structure-in-business-layer/">Bringing together repository and tree structure in business layer</a><br />
Part 2 &#8211;  <a href="http://www.bugfree.dk/blog/2012/12/03/creating-and-working-with-a-custom-tree-data-structure-in-c/">Creating and working with a custom tree data structure in C#</a><br />
Part 1 &#8211; <a href="http://www.bugfree.dk/blog/2012/12/02/strongly-typed-sharepoint-list-operations-using-the-repository-pattern/">Strongly typed SharePoint list operations using the repository pattern</a>
</p>
<p>
As an experiment, I wanted to re-implement the SharePoint repository pattern from Part 1 in F#.
</p>
<pre class="prettyprint lang-ml">
open System
open System.Xml.Linq
open Microsoft.SharePoint
open Microsoft.SharePoint.Taxonomy

type LegalDocument =
    { Title: string
      ApprovalStatus: string
      Locations: seq&lt;string&gt;
      Level: int
      ProcessHierarchy: Map&lt;Guid, string&gt; 
      DocumentId: string
      ParentDocumentId: string
      Url: Uri }

type LegalDocumentRepository() =
    let LinkFilename = "LinkFilename"
    let FileLeafRef = "FileLeafRef"
    let ModerationStatus = "_ModerationStatus"
    let Location = "Location_Legal"
    let ProcessHierarchyLevel = "ProcessHierarchyLevel"
    let ProcessHierarchyLegal = "ProcessHierarchyLegal"
    let DocumentId = "_dlc_DocId"
    let ParentDocumentId = "Parent_x0020_Document_x0020_Id"

    let xn s = XName.Get s

    member __.Query (list: SPList) (caml: XElement): SPListItemCollection =
        let query = 
            SPQuery(
                ViewFields = ([LinkFilename; 
                               ModerationStatus; 
                               Location; 
                               ProcessHierarchyLevel; 
                               ProcessHierarchyLegal; 
                               DocumentId; 
                               ParentDocumentId] |&gt; List.fold (fun acc fld -&gt; 
                                   acc + XElement(xn "FieldRef", XAttribute(xn "Name", xn fld)).ToString()) ""),
                Query = caml.ToString(),
                ViewAttributes =  @"Scope=""RecursiveAll""")
        list.GetItems query

    member this.GetApprovedDocuments (list: SPList) =
        let caml = 
            XElement(xn "Where",
                XElement(xn "Eq",
                    XElement(xn "FieldRef", XAttribute(xn "Name", ModerationStatus)),
                    XElement(xn "Value", XAttribute(xn "Type", xn "ModStat"), "Approved")))
        this.Query list caml |&gt; this.Map

    member __.Map items =
        let levelMapper o =
            let s = o |&gt; string
            match (s |&gt; String.IsNullOrEmpty) with
            | true -&gt; 0
            | false -&gt; 
                let v = s.Split [|':'|]
                match v.Length with
                | 0 -&gt; 0
                | _ -&gt; v.[0] |&gt; int

        let locationMapper (o: obj) = 
            o :?&gt; TaxonomyFieldValueCollection |&gt; Seq.map (fun f -&gt; f.Label)

        let processHierarchyMapper (o: obj) =
            let t = o :?&gt; TaxonomyFieldValueCollection
            t |&gt; Seq.map (fun f -&gt; Guid(f.TermGuid), f.Label)
              |&gt; Map.ofSeq

        let parentDocumentIdMapper o =
            let s = o |&gt; string
            match (String.IsNullOrEmpty s) with
            | true -&gt; ""
            | false -&gt; s.Trim()

        let urlPrefix = items.List.ParentWeb.Url + "/"
        items |&gt; Seq.cast&lt;SPListItem&gt; 
              |&gt; Seq.map (fun i -&gt;
                    { Title = i.[LinkFilename] |&gt; string
                      ApprovalStatus =  i.[ModerationStatus] |&gt; string
                      Locations = locationMapper i.[Location]
                      Level = levelMapper i.[ProcessHierarchyLevel]
                      ProcessHierarchy = processHierarchyMapper i.[ProcessHierarchyLegal] 
                      DocumentId = i.[DocumentId] |&gt; string 
                      ParentDocumentId = parentDocumentIdMapper i.[ParentDocumentId]
                      Url = Uri (urlPrefix + i.Url) })

[&lt;EntryPoint&gt;]
let main args =
    use siteCollection = new SPSite "http://intranet"
    use site = siteCollection.OpenWeb "Legal"
    let list = site.Lists.["LegalDocuments"]
    let repository = LegalDocumentRepository()
    let documents = repository.GetApprovedDocuments list

    documents |&gt; Seq.iter (printfn "%A")
    0
</pre>
<p>
In C#, the cast from string to LINQ to XML type is implicit. In F#, casts are generally explicit so we require the small xn helper function. Using a record type over a regular LegalDocument class has the benefit that all members must be explicitly set on creation or the compiler will issue an error. This comes in handy when modifying LegalDocument during the application life-cycle as the compiler will make sure we update all places where it&#8217;s used.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2012/12/24/strongly-typed-sharepoint-list-operations-using-the-repository-pattern-in-f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bringing together repository and tree structure in business layer</title>
		<link>http://www.bugfree.dk/blog/2012/12/06/bringing-together-repository-and-tree-structure-in-business-layer/</link>
		<comments>http://www.bugfree.dk/blog/2012/12/06/bringing-together-repository-and-tree-structure-in-business-layer/#comments</comments>
		<pubDate>Thu, 06 Dec 2012 19:49:11 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Pattern]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1112</guid>
		<description><![CDATA[This post is part of series: Part 4 &#8211; Strongly typed SharePoint list operations using the repository pattern in F# Part 3 &#8211; Bringing together repository and tree structure in business layer Part 2 &#8211; Creating and working with a custom tree data structure in C# Part 1 &#8211; Strongly typed SharePoint list operations using [...]]]></description>
			<content:encoded><![CDATA[<p>
This post is part of series:
</p>
<p>
Part 4 &#8211; <a href="http://www.bugfree.dk/blog/2012/12/24/strongly-typed-sharepoint-list-operations-using-the-repository-pattern-in-f/">Strongly typed SharePoint list operations using the repository pattern in F#</a><br />
Part 3 &#8211; Bringing together repository and tree structure in business layer<br />
Part 2 &#8211;  <a href="http://www.bugfree.dk/blog/2012/12/03/creating-and-working-with-a-custom-tree-data-structure-in-c/">Creating and working with a custom tree data structure in C#</a><br />
Part 1 &#8211; <a href="http://www.bugfree.dk/blog/2012/12/02/strongly-typed-sharepoint-list-operations-using-the-repository-pattern/">Strongly typed SharePoint list operations using the repository pattern</a>
</p>
<p>Now that we&#8217;ve created the data access layer in the form of a repository to query a SharePoint list and created a supporting tree data structure to re-organize the data returned from the repository, it&#8217;s time to combine the two in the business layer. Because we&#8217;re using the repository to abstract away storage details and the tree structure, as opposed to XML or tree view control APIs, to structure data, the business layer has become easier to reason about. In fact, the business layer can, or perhaps should, be developed as a console application or using a unit testing framework to ensure presentation independence and to work around the very long SharePoint deployment and feedback cycle.</p>
<p>To make the code easier to follow, let’s assume the LegalDocumentRepository.GetDocuments method brings back this set of legal documents from the SharePoint list:</p>
<pre class="prettyprint lang-cs">
new LegalDocument { Title = &quot;node-1&quot;, DocumentId = &quot;node-1&quot;, ParentDocumentId = &quot;root&quot;, Level = 2 },
new LegalDocument { Title = &quot;node-1.1&quot;, DocumentId = &quot;node-1.1&quot;, ParentDocumentId = &quot;node-1&quot;, Level = 3 },
new LegalDocument { Title = &quot;node-1.1.1&quot;, DocumentId = &quot;node-1.1.1&quot;, ParentDocumentId = &quot;node-1.1&quot;, Level = 4 },
new LegalDocument { Title = &quot;node-1.2&quot;, DocumentId = &quot;node-1.2&quot;, ParentDocumentId = &quot;node-1&quot;, Level = 3 },
new LegalDocument { Title = &quot;node-2&quot;, DocumentId = &quot;node-2&quot;, ParentDocumentId = &quot;root&quot;, Level = 2 },
</pre>
<p>The goal is to transform this set of documents into a tree by tying documents together using the DocumentId/ParentDocumentId properties. In doing so, we assume the parent of a document must always be at a lower Level than the child. Thus, building the tree is done by building lower levels first.</p>
<p>Here&#8217;s the business layer class that calls out to the repository and transforms the tabular result into the tree structure:</p>
<pre class="prettyprint lang-cs">public class DocumentBrowser {
    public Tree&lt;LegalDocument&gt; GetDocuments(SPList l) {
        var repository = new LegalDocumentRepository();
        var documents = repository.GetDocuments(l);

        // in the real world, the root LegalDocument instance would also be retrieved from the list.
        var root =
            new Tree&lt;LegalDocument&gt;(new LegalDocument {
                Title = &quot;root&quot;,
                DocumentId = &quot;root&quot;,
                ParentDocumentId = &quot;&quot;,
                Level = 1
            });

        return BuildTree(documents, root);           
    }

    public Tree&lt;T&gt; BuildTree&lt;T&gt;(IEnumerable&lt;T&gt; documents, Tree&lt;T&gt; tree) where T : LegalDocument {
        documents
            .OrderBy(d =&gt; d.Level)
            .ToList()
            .ForEach(d =&gt; {
                var p = tree.Find(pd =&gt; pd.DocumentId == d.ParentDocumentId);
                if (p != null)
                    p.Children.Add(new Tree&lt;T&gt;(d));
            });

        return tree;
    }
}</pre>
<p>A console application that exercises the business layer looks like so:</p>
<pre class="prettyprint lang-cs">public static void Main() {
    using (var siteCollection = new SPSite(&quot;http://intranet&quot;)) {
        using (var site = siteCollection.OpenWeb(&quot;Legal&quot;)) {
            var list = site.Lists[&quot;LegalDocuments&quot;];
            var documentBrowser = new DocumentBrowser();
            var tree = documentBrowser.GetDocuments(list);
            System.Console.WriteLine(tree);

            /*
             root
               node-1
                 node-1.1
                   node-1.1.1
                 node-1.2
               node-2
            */
        }
    }
}</pre>
<p>Ultimately, the layering introduces more classes and code, but the code becomes more abstract, less cluttered, easier to read, and faster to debug.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2012/12/06/bringing-together-repository-and-tree-structure-in-business-layer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating and working with a custom tree data structure in C#</title>
		<link>http://www.bugfree.dk/blog/2012/12/03/creating-and-working-with-a-custom-tree-data-structure-in-c/</link>
		<comments>http://www.bugfree.dk/blog/2012/12/03/creating-and-working-with-a-custom-tree-data-structure-in-c/#comments</comments>
		<pubDate>Mon, 03 Dec 2012 10:13:06 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1106</guid>
		<description><![CDATA[This post is part of series: Part 4 &#8211; Strongly typed SharePoint list operations using the repository pattern in F# Part 3 &#8211; Bringing together repository and tree structure in business layer Part 2 &#8211; Creating and working with a custom tree data structure in C# Part 1 &#8211; Strongly typed SharePoint list operations using [...]]]></description>
			<content:encoded><![CDATA[<p>
This post is part of series:
</p>
<p>
Part 4 &#8211; <a href="http://www.bugfree.dk/blog/2012/12/24/strongly-typed-sharepoint-list-operations-using-the-repository-pattern-in-f/">Strongly typed SharePoint list operations using the repository pattern in F#</a><br />
Part 3 &#8211; <a href="http://www.bugfree.dk/blog/2012/12/06/bringing-together-repository-and-tree-structure-in-business-layer/">Bringing together repository and tree structure in business layer</a><br />
Part 2 &#8211;  Creating and working with a custom tree data structure in C#<br />
Part 1 &#8211; <a href="http://www.bugfree.dk/blog/2012/12/02/strongly-typed-sharepoint-list-operations-using-the-repository-pattern/">Strongly typed SharePoint list operations using the repository pattern</a>
</p>
<p>I’d claim the tree data structure is underused in general application development. Sure, XML or tree view control APIs are generally tree-based underneath, but how often does an application use a tree structure in its business layer? Maybe it’s because trees are initially a little hard to grasp given their recursive nature or maybe it’s because we as developers are conditioned to approach problems from a more imperative angle.</p>
<p>It wasn’t until recently, when I had to transform a tabular data structure into a tree data structure, that I created my own tree in C#. Here&#8217;s the code I ended up with for constructing a tree, doing a depth-first search for a node, and printing the tree:</p>
<pre class="prettyprint lang-cs">public class Tree&lt;T&gt; {
    public T Value;
    public IList&lt;Tree&lt;T&gt;&gt; Children;

    public Tree(T value) {
        Value = value;
        Children = new List&lt;Tree&lt;T&gt;&gt;();
    }

    public Tree&lt;T&gt; Find(Func&lt;T, bool&gt; predicate) {
        if (predicate(Value))
            return this;
           
        return Children
            .Select(c =&gt; c.Find(predicate))
            .FirstOrDefault(c =&gt; c != null);
    }

    public override string ToString() {
        return ToStringRecursive(this, 0);
    }

    private string ToStringRecursive(Tree&lt;T&gt; tree, int indentation) {
        var seed = (new String(' ', indentation)) + tree.Value + Environment.NewLine;
        return tree
            .Children
            .Aggregate(seed, (current, next) =&gt; current + 
                ToStringRecursive(next, indentation + 2));
    }
}</pre>
<p>Constructing a tree of strings is done as follows:</p>
<pre class="prettyprint lang-cs">var root = new Tree&lt;string&gt;(&quot;root&quot;) {
    Children = new List&lt;Tree&lt;string&gt;&gt; {
        new Tree&lt;string&gt;(&quot;node-1&quot;) {
            Children = new List&lt;Tree&lt;string&gt;&gt; {
                new Tree&lt;string&gt;(&quot;node-1.1&quot;) {
                    Children = new List&lt;Tree&lt;string&gt;&gt; {
                        new Tree&lt;string&gt;(&quot;node-1.1.1&quot;)  
                    }
                },
                new Tree&lt;string&gt;(&quot;node-1.2&quot;)
            }
        },
        new Tree&lt;string&gt;(&quot;node-2&quot;)
    }
};</pre>
<p>Now you can query on the properties of the type of tree node:</p>
<pre class="prettyprint lang-cs">System.Console.WriteLine(root);
/*
root
  node-1
    node-1.1
      node-1.1.1
    node-1.2
  node-2
*/

var node1 = root.Find(n =&gt; n == &quot;node-1&quot;);
var node2 = node1.Find(n =&gt; n == &quot;node-1.1.1&quot;);

System.Console.WriteLine(node1);
/*
node-1
  node-1.1
    node-1.1.1
  node-1.2
*/

System.Console.WriteLine(node2);
/*
node-1.1.1            
*/</pre>
<p>Strictly speaking, the traversal logic doesn’t belong to the tree class itself, but in a separate visitor class. Maybe at a later point, you want to add different traversal algorithms or some other code needs to iterate the tree to transform it. The visitor algorithms could be reused, calling out to a delegate for the specific details of the traversal.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2012/12/03/creating-and-working-with-a-custom-tree-data-structure-in-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Strongly typed SharePoint list operations using the repository pattern</title>
		<link>http://www.bugfree.dk/blog/2012/12/02/strongly-typed-sharepoint-list-operations-using-the-repository-pattern/</link>
		<comments>http://www.bugfree.dk/blog/2012/12/02/strongly-typed-sharepoint-list-operations-using-the-repository-pattern/#comments</comments>
		<pubDate>Sun, 02 Dec 2012 15:54:08 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Pattern]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1105</guid>
		<description><![CDATA[This post is part of series: Part 4 &#8211; Strongly typed SharePoint list operations using the repository pattern in F# Part 3 &#8211; Bringing together repository and tree structure in business layer Part 2 &#8211; Creating and working with a custom tree data structure in C# Part 1 &#8211; Strongly typed SharePoint list operations using [...]]]></description>
			<content:encoded><![CDATA[<p>
This post is part of series:
</p>
<p>
Part 4 &#8211; <a href="http://www.bugfree.dk/blog/2012/12/24/strongly-typed-sharepoint-list-operations-using-the-repository-pattern-in-f/">Strongly typed SharePoint list operations using the repository pattern in F#</a><br />
Part 3 &#8211; <a href="http://www.bugfree.dk/blog/2012/12/06/bringing-together-repository-and-tree-structure-in-business-layer/">Bringing together repository and tree structure in business layer</a><br />
Part 2 &#8211;  <a href="http://www.bugfree.dk/blog/2012/12/03/creating-and-working-with-a-custom-tree-data-structure-in-c/">Creating and working with a custom tree data structure in C#</a><br />
Part 1 &#8211; Strongly typed SharePoint list operations using the repository pattern
</p>
<p>I first wrote about <a href="http://www.bugfree.dk/blog/2010/01/18/sharepoint-list-access-using-the-repository-pattern/">accessing SharePoint lists using the repository pattern</a> about three years ago. Since then I&#8217;ve reused that approach, with a few improvements, on almost every SharePoint project I&#8217;ve worked on. The improvements include generating CAML queries using LINQ to XML, taking a more functional approach to mapping from loosely typed to strongly typed data, passing in more specific arguments, not tying the repository to a definition class, and removing assertions to focus more on <a href="http://simpleprogrammer.com/2012/04/16/validate-user-input-not-developer-input/">validating user rather than developer input</a>.</p>
<p>Depicted graphically, here’s what I want my repository to do, albeit in a less sophisticated way than the <a href="http://msdn.microsoft.com/en-us/library/ff649690.aspx">SharePoint guidance</a> by the Patterns &amp; Practices team:</p>
<p><a href="http://www.bugfree.dk/blog/wp-content/uploads/2012/12/IC3402331.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="IC340233" border="0" alt="IC340233" src="http://www.bugfree.dk/blog/wp-content/uploads/2012/12/IC340233_thumb1.png" width="400" height="140" /></a></p>
<p>As an example, suppose I have a SharePoint list containing the internal fields below. Accessing field values through the <a href="http://msdn.microsoft.com/en-us/library/ms464204.aspx">SPListItem.Item property</a> yields results of type object, which may then be cast to the type of the input type column. For some fields, such as Location_Legal and Url, I not only want to project it onto a differently named field but also a different type as indicted by the Output type column. The type may be changed to one that is more precise and/or easier to work with, given the client&#8217;s requirements. As a final note, observe how the internal names are inconsistently named. The repository can help bring some order to the naming and type chaos:</p>
<table width="756">
<tbody>
<tr>
<th width="176">
<p align="left">Internal name</p>
</th>
<div align="left"></div>
<th width="167">Strongly typed name</th>
<div></div>
<div align="left"></div>
<th width="220">Input type</th>
<div></div>
<th width="191">
<p align="left">Output type</p>
</th>
</tr>
<tr>
<td width="176">LinkFilename</td>
<td width="167">Title</td>
<td width="220">string</td>
<td width="191">string</td>
</tr>
<tr>
<td width="176">_ModerationStatus</td>
<td width="167">ApprovalStatus</td>
<td width="220">string</td>
<td width="191">string</td>
</tr>
<tr>
<td width="176">Location_Legal</td>
<td width="167">Locations</td>
<td width="220">TaxonomyFieldValueCollection</td>
<td width="191">IList&lt;string&gt;</td>
</tr>
<tr>
<td width="176">ProcessHierarchyLevel</td>
<td width="167">Level</td>
<td width="220">string</td>
<td width="191">int</td>
</tr>
<tr>
<td width="176">Url</td>
<td width="167">Url</td>
<td width="220">string</td>
<td width="191">Uri</td>
</tr>
<tr>
<td width="176">ProcessHierarchyLegal</td>
<td width="167">ProcessHierarchy</td>
<td width="220">TaxonomyFieldValueCollection</td>
<td width="191">IDictionary&lt;Guid, string&gt;</td>
</tr>
<tr>
<td width="176">_dlc_DocId</td>
<td width="167">DocumentId</td>
<td width="220">string</td>
<td width="191">string</td>
</tr>
<tr>
<td width="176">Parent Document Id</td>
<td width="167">ParentDocumentId</td>
<td width="220">string</td>
<td width="191">string</td>
</tr>
</tbody>
</table>
<p>Here&#8217;s an example of a simple repository with read operations only. It&#8217;s easily extended with create, update, and delete operations. Don&#8217;t pay too much attention to the concrete fields. They&#8217;re meant as&#160; examples:</p>
<pre class="prettyprint lang-cs">public class LegalDocument {
    public string Title;
    public string ApprovalStatus;
    public IList&lt;string&gt; Locations;
    public int Level;
    public Uri Url;
    public IDictionary&lt;Guid, string&gt; ProcessHierarchy;
    public string DocumentId;
    public string ParentDocumentId;
}

public class LegalDocumentRepository {
    const string LinkFilename = &quot;LinkFilename&quot;;
    const string FileLeafRef = &quot;FileLeafRef&quot;;
    const string ModerationStatus = &quot;_ModerationStatus&quot;;
    const string Location = &quot;Location_Legal&quot;;
    const string ProcessHierarchyLevel = &quot;ProcessHierarchyLevel&quot;;
    const string ProcessHierarchyLegal = &quot;ProcessHierarchyLegal&quot;;
    const string DocumentId = &quot;_dlc_DocId&quot;;
    const string ParentDocumentId = &quot;Parent_x0020_Document_x0020_Id&quot;;

    protected SPListItemCollection Query(SPList list, XElement caml) {
        var query = new SPQuery { 
            Query = caml.ToString(),
            ViewFields = new[] { 
                LinkFilename, 
                ModerationStatus, 
                Location,
                ProcessHierarchyLevel, 
                ProcessHierarchyLegal,
                DocumentId,
                ParentDocumentId }
                    .Aggregate(&quot;&quot;, (acc, fld) =&gt;
                        acc + (new XElement(&quot;FieldRef&quot;, new XAttribute(&quot;Name&quot;, fld)).ToString())),
            ViewAttributes = @&quot;Scope=&quot;&quot;RecursiveAll&quot;&quot;&quot;
        };

        var result = list.GetItems(query);      
        return result;
    }

    public LegalDocument GetByFilename(SPList list, string filename) {
        var caml =
            new XElement(&quot;Where&quot;,
                new XElement(&quot;Eq&quot;,
                    new XElement(&quot;FieldRef&quot;, new XAttribute(&quot;Name&quot;, FileLeafRef)),
                    new XElement(&quot;Value&quot;, new XAttribute(&quot;Type&quot;, &quot;Text&quot;), filename)));
        var result = Query(list, caml);
        return Map(result).Single();
    }

    public IEnumerable&lt;LegalDocument&gt; GetApprovedDocuments(SPList list) {
        var caml =
            new XElement(&quot;Where&quot;,
                new XElement(&quot;Eq&quot;,
                    new XElement(&quot;FieldRef&quot;, new XAttribute(&quot;Name&quot;, ModerationStatus)),
                    new XElement(&quot;Value&quot;, new XAttribute(&quot;Type&quot;, &quot;ModStat&quot;), &quot;Approved&quot;)));
        var result = Query(list, caml);
        return Map(result);
    }

    private IEnumerable&lt;LegalDocument&gt; Map(SPListItemCollection items) {
        Func&lt;object, int&gt; levelMapper = o =&gt; {
            var s = (string) o;
            if (string.IsNullOrEmpty(s))
                return 0;
            var v = s.Split(new[] { ':' });
            return v.Length == 0 ? 0 : int.Parse(v[0]);
        };

        Func&lt;object, IList&lt;string&gt;&gt; locationMapper = o =&gt; {
            var t = (TaxonomyFieldValueCollection) o;
            return t.Select(f =&gt; f.Label).ToList();
        };

        Func&lt;object, IDictionary&lt;Guid, string&gt;&gt; processHierarchyMapper = o =&gt; {
            var t = (TaxonomyFieldValueCollection) o;
            var kvp = new Dictionary&lt;Guid, string&gt;();
            t.ForEach(f =&gt; kvp.Add(new Guid(f.TermGuid), f.Label));
            return kvp;
        };

        Func&lt;object, string&gt; parentDocumentId = o =&gt; {
            var s = (string)o;
            return string.IsNullOrEmpty(s) ? &quot;&quot; : s.Trim();
        };

        var urlPrefix = items.List.ParentWeb.Url + &quot;/&quot;;
        var documents = 
            from SPListItem i in items
            select new LegalDocument {
                Title = (string) i[LinkFilename], 
                ApprovalStatus = (string) i[ModerationStatus], 
                Locations = locationMapper(i[Location]), 
                Level = levelMapper(i[ProcessHierarchyLevel]), 
                ProcessHierarchy = processHierarchyMapper(i[ProcessHierarchyLegal]), 
                DocumentId = (string) i[DocumentId], 
                ParentDocumentId = parentDocumentId(i[ParentDocumentId]),
                Url = new Uri(urlPrefix + i.Url)
            };

        return documents;
    }
}</pre>
<p>The repository code has a number of interesting points to be aware of:</p>
<ul>
<li>Only include the fields required by the client in the CAML query. Extra fields will have a negative impact on mapping performance and creates a high coupling between the repository and the SharePoint list. This coupling may prevent future updates to fields without updating and re-deploying the repository as well. </li>
<li>Calling <a href="http://msdn.microsoft.com/en-us/library/ms457534.aspx">SPList.GetItems()</a> only takes a few milliseconds. The expensive part is materializing the result collection. Replacing the call with one to <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splist.getdatatable.aspx">SPList.GetDataTable()</a> doesn&#8217;t change anything, except that now the repository’s Query method, rather than the Map method, is where the majority of the execution time is spent. </li>
<li>Each of the repository access methods, such as GetApprovedDocuments, accepts a SPList instance. The calling code must take of getting hold of an appropriate SPList instance. In case a repository method require access to the list’s parent SPWeb or SPSite instance, they&#8217;re available through the SPList instance. </li>
<li>The LINQ to XML code is more verbose than the equivalent string representation of a CAML query, but prevents certain types of syntax errors from creeping into the query. Complex structures, strings in this case, should generally be constructed by a builder that encapsulates the details of the structure. </li>
<li>Whether to create many smaller repositories or a large one that combines all the operations on a list is a matter of taste and general application architecture. Maybe the architecture consists of multiple <a href="http://en.wikipedia.org/wiki/Domain-driven_design#Bounded_context">bounded context</a> in which case multiple repositories would make sense. </li>
<li>The mapping within the Map method is lazy. Only when the client enumerates the collection, or calls <a href="http://msdn.microsoft.com/en-us/library/bb342261.aspx">ToList()</a> on it to force immediate query evaluation, does the mapping of each item take place. Depending on how you plan to use the repository, it may or may not make sense to return an lazily evaluated collection. </li>
<li>Unit testing code that makes use of a repository becomes simpler. The repository can implement an interface through which your clients access it, enabling you to inject a fake repository into your business logic. Alternatively, your mocking framework may be capable of mocking a concrete class. </li>
<li>LINQ to SharePoint could be used as an alternative to writing CAML queries by hand. I’ve refrained from using it because I think it adds unnecessary complexity and no value to the solution. </li>
</ul>
<p>With this simple repository abstraction, I&#8217;ve created a data access layer that the business layer can call into and get back objects and collections of objects almost as if they’re in-memory objects, hiding away most of the SharePoint data access intricacies.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2012/12/02/strongly-typed-sharepoint-list-operations-using-the-repository-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Disabling SharePoint 2010 in-place records management and undeclaring records</title>
		<link>http://www.bugfree.dk/blog/2012/11/28/disabling-sharepoint-2010-in-place-records-management-and-undeclaring-records/</link>
		<comments>http://www.bugfree.dk/blog/2012/11/28/disabling-sharepoint-2010-in-place-records-management-and-undeclaring-records/#comments</comments>
		<pubDate>Wed, 28 Nov 2012 08:00:06 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Powershell]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1102</guid>
		<description><![CDATA[After having used the SharePoint 2010 in-place records management for some time, we might decide that we don&#8217;t require records management on a library after all. We want to go back to regular, modifiable documents, undeclare any existing record, and prevent future items from becoming records. Suppose a site collection needs to have in-place records [...]]]></description>
			<content:encoded><![CDATA[<p>After having used the SharePoint 2010 in-place records management for some time, we might decide that we don&#8217;t require records management on a library after all. We want to go back to regular, modifiable documents, undeclare any existing record, and prevent future items from becoming records.</p>
<p>Suppose a site collection needs to have in-place records management disabled entirely. Then the first step would be to disable the site collection-scoped In Place Records Management feature:</p>
<pre class="prettyprint">
disable-spfeature -identity InPlaceRecords -url $site_collection_url
</pre>
<p>However, what actually triggers the declaration of a record is the retention policy on a document library or its containing content type. Thus, removing the retention policy prevents future items from becoming records. On the document library or its containing content type, goto the Information management policy settings and disable the retention policy:</p>
<p><a href="http://www.bugfree.dk/blog/wp-content/uploads/2012/11/Enable-retention-example.png"><img style="background-image: none; border-right-width: 0px; margin: 3px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Enable-retention-example" border="0" alt="Enable-retention-example" src="http://www.bugfree.dk/blog/wp-content/uploads/2012/11/Enable-retention-example.png"/></a></p>
<p>Existing records will remain unaffected by the feature deactivation and the disabling of the retention policy. We need to enumerate the document library and undeclare each exising record:</p>
<pre class="prettyprint">
function UndeclareRecords($siteUrl, $libraryName) {
  function IsRecord($item) {
    [Microsoft.Office.RecordsManagement.RecordsRepository.Records]::IsRecord($item)
  }

  function EnsureCheckedIn($item) {
    if ($item.File.CheckOutType -ne [Microsoft.SharePoint.SPFile+SPCheckOutType]::None `
        -and (-not [Microsoft.Office.RecordsManagement.RecordsRepository.Records]::IsLocked)) {
      write-host "Checking in file: $($item.Url)"
      $file.CheckIn("Checked in by script prior to undeclaring as record", `
                    [Microsoft.SharePoint.SPCheckinType]::MinorCheckIn)
    }
  }

  function UndeclareRecord($item) {
    write-host "Undeclaring record: $($item.Url)"
    [Microsoft.Office.RecordsManagement.RecordsRepository.Records]::UndeclareItemAsRecord($item) 
  }

  $site = Get-SPWeb $siteUrl
  $list = $site.Lists[$libraryName]
  $list.Items | foreach { 
    if (IsRecord $_) {
      EnsureCheckedIn $_
      UndeclareRecord $_
    }
  }

  $site.Dispose()
}
</pre>
<p>
Now every item in the document library is back to being a regular and modifiable item.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2012/11/28/disabling-sharepoint-2010-in-place-records-management-and-undeclaring-records/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Effective ML (and F#)</title>
		<link>http://www.bugfree.dk/blog/2012/06/24/effective-ml-and-f/</link>
		<comments>http://www.bugfree.dk/blog/2012/06/24/effective-ml-and-f/#comments</comments>
		<pubDate>Sun, 24 Jun 2012 12:15:00 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[F#]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1098</guid>
		<description><![CDATA[This is a summary of Yaron Minsky’s nine pieces of advice from the Effective ML video. Since ML is a predecessor of F#, most of the advice applies to F# as well. 1. Favor readers over writers (10:20). There’re systematic differences in opinion between those who spent their time reading code and those who spent [...]]]></description>
			<content:encoded><![CDATA[<p>This is a summary of <a href="http://twitter.com/#!/yminsky">Yaron Minsky</a>’s nine pieces of advice from the <a href="http://vimeo.com/14313378">Effective ML</a> video. Since ML is a predecessor of F#, most of the advice applies to F# as well.</p>
<p><strong>1. Favor readers over writers (10:20)</strong>. There’re systematic differences in opinion between those who spent their time reading code and those who spent it writing code. Whenever there’s a difference in opinion between these two groups, the readers are always right and the writers are always wrong. The readers will always push in the direction of clarity and simplicity and the ability to change behavior easily. At least if you’re building software that’s going to last. </p>
<p><strong>2. Create uniform interfaces (12:15)</strong>. Always create an interface to your code to make it easier on the reader. When you build interfaces, you should have standards that apply uniformly across your code base to build solid expectations. Those who use your code should know what to provide and what to expect when interfacing with your codebase.</p>
<p><strong>3. Make illegal states unrepresentable (18:03)</strong>. Use the type system as a tool to enforce invariants on the code you write. Choose your data types such that states that are illegal don’t show up as legal states in the program. Take this code representing various connection information as an example. It keeps track of relevant information in a fairly readable manner: </p>
<pre class="prettyprint lang-ml">type connection_state =
  | Connecting
  | Connected
  | Disconnected

type connection_info = {
    state:             connection_state
    server:            IPAddress
    last_ping_time:    DateTime option
    last_ping_id:      int option
    session_id:        string option
    when_initiated:    DateTime option
    when_disconnected: DateTime option
}</pre>
<p>On the surface these types look reasonable, but there’re some tricky invariants that need to hold about the data. For instance, if you have a last_ping_time, you should probably also have a last_ping_id and vice versa. And the session_id and when_initiated probably only makes sense when you’re connected. Similarly, when_disconnected only makes sense if and when you’ve been disconnected.</p>
<p>The key is that there’s nothing about the types that help you enforce all these invariants. A better approach would be to refactor the connection_info into a series of types where the invariants would be inherent in the types themselves rather than being implicit in the logic surrounding the types:</p>
<pre class="prettyprint lang-ml">type connecting = { when_initiated: DateTime }
type connected = { last_ping: (DateTime * int) option
                   session_id: string }
type disconnected = { when_connected: DateTime }

type connection_state =
  | Connecting of connecting
  | Connected of connected
  | Disconnected of disconnected

type connection_info = {
    state: connection_state
    server: IPAddress
}</pre>
<p>server remains in connection_info because it applies to any of the states. The other information have been grouped together with the state it related to. The different connection_states are no longer merely a simple enumerated type but each of the different tags have content. Note also how the last_ping is now both the last_ping_time and last_ping_id. Either both are present, and grouped together, or not.</p>
<p><strong>4. Code for exhaustiveness (28:33)</strong>. This one is closely related to making illegal states unrepresentable in that you should write your code aiming at exhaustiveness guarantees. For instance, when you have a match statement, the compiler will warn you if the match is not exhaustive. The key benefit is as a refactoring tool because it guides changes in the code base. Don’t use the match all (_ –&gt; …) because it means that if you expand on the discriminated union the compiler will not warn you.</p>
<p><strong>5. Open few modules (34:08)</strong>. When you open a module, it makes your code a bit shorter, and that’s great for the guy who wrote the code, but not the guy reading it. Now you can no longer just look at the code and tell where the value came from. In F#, with Visual Studio integration and IntelliSense, this is less of a problem. But the key advice is to respect the cognitive limitation of the people reading the code. If you want people to remember something, make them remember only for a short period of time. </p>
<p><strong>6. Make common errors obvious (38:10)</strong>. Use exceptions for exceptional conditions is what people often tell you. But whether something is a common case depends on context. For instance, in one context it’s an error if an element isn’t in a list, whereas in others it’s perfectly acceptable. For your API it may depend on the caller if a case is exceptional or not. To better support the caller, you could create two versions depending on how you want to communicate an error:</p>
<pre class="prettyprint lang-ml">val hd : 'T list -&gt; 'T option
val hd_exn : 'T list -&gt; 'T</pre>
<p>Now you can tell from the name of the function weather it throws an exception or not. For people reading the code it makes it easier to understand the error behavior of the code.</p>
<p><strong>7. Avoid boilerplate (40:52)</strong>. Avoid repeating the same code, or almost the same code, in multiple places. Boilerplate appears, in general, because people have a cut and paste template they use to do almost the same thing in multiple spots and because their language isn’t good enough to encode what they want to do in a clean way. You want to get rid of boilerplate because the structure you’re repeating is there for a reason, and your code evolves. At that point you’re not going to remember all the places where the repetition shows up. It also goes back to readability. It’s hard to convince people to read code if it’s dull. And nothing is duller than boilerplate, even though the code is critical.</p>
<p>Interestingly, reducing boilerplate doesn’t always make code less verbose. The goal isn’t to make the code shorter but to separate out which parts of the code is the same and which parts vary.</p>
<p><strong>8. Avoid complex type hackery (45:30)</strong>. The enemy of good code, of correctness, is not dynamic guarantees, properties about the code that cannot be proved at compile time, but complexity. Refrain from making your code more complex (using <a href="http://mlton.org/PhantomType">phantom types</a>, for instance), just so you can have the type system verify additional properties of the code.</p>
<p><strong>9. Don’t be puritanical about purity (47:10)</strong>. Avoiding side-effect is generally worth striving for, because code without side-effects tends to be easier to reason about. But sometimes it’s also just easier to code with side-effects. There may even be performance reasons for allowing side-effects so don’t be embarrassed about it. In reality, programs don’t just compute things, they do things like write files, send messages, and so on. All this doing involves side-effects. Again, remember that the enemy of correctness is complexity. Don’t jump through hoops to make your code too complex just to make it pure.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2012/06/24/effective-ml-and-f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How F# discriminated unions translate to C# code</title>
		<link>http://www.bugfree.dk/blog/2012/06/23/how-f-discriminated-unions-translate-to-c-code/</link>
		<comments>http://www.bugfree.dk/blog/2012/06/23/how-f-discriminated-unions-translate-to-c-code/#comments</comments>
		<pubDate>Sat, 23 Jun 2012 09:51:00 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[F#]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1097</guid>
		<description><![CDATA[Here’s another useful insight from Ivan Towlson‘s A Practical Developer’s Introduction to F#. Record types are limited by the fact that they have a single schema. In most applications, however, you want to store different shapes of data depending on different cases. In C#, we might do so using a class hierarchy with a base [...]]]></description>
			<content:encoded><![CDATA[<p>Here’s another useful insight from <a href="http://hestia.typepad.com/flatlander">Ivan Towlson</a>‘s <a href="http://channel9.msdn.com/Events/TechEd/NewZealand/2011/DEV311">A Practical Developer’s Introduction to F#</a>.</p>
<p><a href="http://www.bugfree.dk/blog/2012/06/22/how-f-record-types-translate-to-c-code/">Record types</a> are limited by the fact that they have a single schema. In most applications, however, you want to store different shapes of data depending on different cases. In C#, we might do so using a class hierarchy with a base class keeping common state and subclasses keeping their own.</p>
<p>F# models a similar concept of hierarchical types using the discriminated union type. For instance, this discriminated union represents the result of a function that might succeed or might fail:</p>
<pre class="prettyprint lang-ml">type Errorable&lt;'a&gt; =
  | Success of 'a
  | Error of string</pre>
<p>If you disassemble the generated IL, the result is a class hierarchy. It has compare, equals, and hash code methods, like record types, but they’re placed on the base class. Factory methods are provided to create instances of the closed set of subtypes, and predicate methods are provided to check if an instance is of some type. In addition, each subtype has a constructor generated for it, accepting the argument following the “of” keyword, called the value constructor. Like record types, discriminated union types are immutable, which is why they’ve getter properties but no setters:</p>
<pre class="prettyprint lang-cs">[Serializable, CompilationMapping(SourceConstructFlags.SumType)]
public abstract class Errorable&lt;a&gt; : IEquatable&lt;Errorable&lt;a&gt;&gt;, IStructuralEquatable,
                      IComparable&lt;Errorable&lt;a&gt;&gt;, IComparable, IStructuralComparable {
    // Methods
    internal Errorable();
    public sealed override int CompareTo(Errorable&lt;a&gt; obj);
    public sealed override int CompareTo(object obj);
    public sealed override int CompareTo(object obj, IComparer comp);
    public sealed override bool Equals(Errorable&lt;a&gt; obj);
    public sealed override bool Equals(object obj);
    public sealed override bool Equals(object obj, IEqualityComparer comp);
    public sealed override int GetHashCode();
    public sealed override int GetHashCode(IEqualityComparer comp);
    public static Errorable&lt;a&gt; NewError(string item);
    public static Errorable&lt;a&gt; NewSuccess(a item);

    // Properties
    public bool IsError { get; }
    public bool IsSuccess { get; }
    public int Tag { get; }

    // Nested Types
    [Serializable]
    public class Error : Errorable&lt;a&gt; {
        internal readonly string item;
        internal Error(string item);
        public string Item { get; }
    }

    [Serializable]
    public class Success : Errorable&lt;a&gt; {
        internal readonly a item;
        internal Success(a item);
        public a Item { get; }
    }

    public static class Tags {
        public const int Error = 1;
        public const int Success = 0;
    }
}</pre>
<p>In an object-oriented language, you typically operate on a class hierarchy through virtual methods on the classes. Say you want to display the Errorable type, then you’d implement a virtual method on the Error and Success subclasses with behavior specific to the each type. In a functional language, the organizing principle is by function. You write one display function that use pattern matching to dispatch on the different cases:</p>
<pre class="prettyprint lang-ml">let display x =
    match x with
    | Error e -&gt; &quot;Oh no! &quot; + e
    | Success a -&gt; a.ToString()</pre>
<p>The variable names &#8212; e and a &#8212; get bound to the content of the case at hand. For the Error case, e is the error message, while for the success case a is the success value, whatever generic type it is.</p>
<p>Provided you leave out the match all case (_ –&gt; &#8230;), a powerful feature of discriminated unions and pattern matching over classes and virtual methods is that the compiler is able to enforce that no cases have been forgotten, that no redundant cases exist, and that there’re no impossible cases. In C#, you’d encounter a missing case at runtime only if you remember to put in a catch all else or default case statement.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2012/06/23/how-f-discriminated-unions-translate-to-c-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How F# record types translate to C# code</title>
		<link>http://www.bugfree.dk/blog/2012/06/22/how-f-record-types-translate-to-c-code/</link>
		<comments>http://www.bugfree.dk/blog/2012/06/22/how-f-record-types-translate-to-c-code/#comments</comments>
		<pubDate>Fri, 22 Jun 2012 08:20:00 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[F#]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1095</guid>
		<description><![CDATA[Here’s another useful insight from Ivan Towlson‘s A Practical Developer’s Introduction to F#. Suppose you want to store information about a person in F#, then the build-in record type provides a nice way of grouping related data together: type Person = { Name: string; Age: int } Decompiling the generated IL and coming at it [...]]]></description>
			<content:encoded><![CDATA[<p>Here’s another useful insight from <a href="http://hestia.typepad.com/flatlander">Ivan Towlson</a>‘s <a href="http://channel9.msdn.com/Events/TechEd/NewZealand/2011/DEV311">A Practical Developer’s Introduction to F#</a>.</p>
<p>Suppose you want to store information about a person in F#, then the build-in record type provides a nice way of grouping related data together:</p>
<pre class="prettyprint lang-ml">type Person = { Name: string; Age: int }</pre>
<p>Decompiling the generated IL and coming at it from a C# angle provides for an interesting exercise. It not only shows how terse F# can be, but also how easy it is to consume F# types from other .NET languages (decompiled IL is method signatures only, not actual implementation): </p>
<pre class="prettyprint lang-cs">[Serializable, CompilationMapping(SourceConstructFlags.RecordType)]
public sealed class Person : IEquatable&lt;Person&gt;, IStructuralEquatable, IComparable&lt;Person&gt;, 
                             IComparable, IStructuralComparable {
    // Fields
    [DebuggerBrowsable(DebuggerBrowsableState.Never)] internal int Age@;
    [DebuggerBrowsable(DebuggerBrowsableState.Never)] internal string Name@;

    // Methods
    public Person(string name, int age);
    [CompilerGenerated] public sealed override int CompareTo(Person obj);
    [CompilerGenerated] public sealed override int CompareTo(object obj);
    [CompilerGenerated] public sealed override int CompareTo(object obj, IComparer comp);
    [CompilerGenerated] public sealed override bool Equals(Person obj);
    [CompilerGenerated] public sealed override bool Equals(object obj);
    [CompilerGenerated] public sealed override bool Equals(object obj, IEqualityComparer comp);
    [CompilerGenerated] public sealed override int GetHashCode();
    [CompilerGenerated] public sealed override int GetHashCode(IEqualityComparer comp);

    // Properties
    [CompilationMapping(SourceConstructFlags.Field, 1)] public int Age { get; }
    [CompilationMapping(SourceConstructFlags.Field, 0)] public string Name { get; }
}</pre>
<p>Observe how a public constructor has been generated, accepting arguments in the order in which the record was defined, and how only getter properties for Name and Age exist. That’s because the record type is immutable. The value of Person can only be set once using the constructor. Finally, compare, equals, and hash code methods for doing value comparisons, implementing all the proper interfaces, have been compiler-generated as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2012/06/22/how-f-record-types-translate-to-c-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simplifying F# lambda expressions with partial function application</title>
		<link>http://www.bugfree.dk/blog/2012/06/21/simplifying-f-lambda-expressions-with-partial-function-application/</link>
		<comments>http://www.bugfree.dk/blog/2012/06/21/simplifying-f-lambda-expressions-with-partial-function-application/#comments</comments>
		<pubDate>Thu, 21 Jun 2012 13:33:00 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[F#]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1096</guid>
		<description><![CDATA[Here’s another useful trick from Ivan Towlson&#8216;s A Practical Developer&#8217;s Introduction to F#. Suppose you have a function divisiblyBy and a list of numbers. Then you can apply the filter function to get a list of even numbers: // val divisibleBy : int -&#62; int -&#62; bool let divisibleBy factor value = value % factor [...]]]></description>
			<content:encoded><![CDATA[<p>Here’s another useful trick from <a href="http://hestia.typepad.com/flatlander">Ivan Towlson</a>&#8216;s <a href="http://channel9.msdn.com/Events/TechEd/NewZealand/2011/DEV311">A Practical Developer&#8217;s Introduction to F#</a>.</p>
<p>Suppose you have a function divisiblyBy and a list of numbers. Then you can apply the filter function to get a list of even numbers:</p>
<pre class="prettyprint lang-ml">// val divisibleBy : int -&gt; int -&gt; bool
let divisibleBy factor value = value % factor = 0
let evenNums = List.filter (fun x -&gt; divisibleBy 2 x) [1..10]</pre>
<p>This lambda syntax is a bit noisy, but can oftentimes be transformed into a shorthand lambda syntax. When the argument passed into the lambda &#8212; in this case x &#8212; is the last argument to the function within the lambda body, a bit of compiler trickery combined with the use of partial function application can help simplify the expression. Combining partial function application with function composition even means we don’t have to explicitly create a lot of smaller functions, such as one that negates another function:</p>
<pre class="prettyprint lang-ml">let evenNums = List.filter (divisibleBy 2) [1..10]       // partial function application
let oddNums = List.filter (not &lt;&lt; divisibleBy 2) [1..10] // and function composition</pre>
<p>Of course, the concept of partial function application isn’t tied to lambda expressions:</p>
<pre class="prettyprint lang-ml">let divisibleByTwo = divisibleBy 2           // val divisibleByTwo : (int -&gt; bool)
let notDivisibleByTwo = not &lt;&lt; divisibleBy 2 // val notDivisibleByTwo : (int -&gt; bool)
let a = divisibleByTwo 4                     // val a : bool = true
let b = notDivisibleByTwo 4                  // val b : bool = false</pre>
<p>The partial application of divisibleBy results in a new function of one less argument, since we provided a value for the factor argument. As you can tell by their signatures, divisibleByTwo and notDivisibleByTwo are functions that take one argument, the value, and return a bool. The compiler knows that divisibleByTwo and notDivisibleByTwo take one and only argument for them to fully evaluate and that filter takes as argument a function that goes from an argument of type ‘T &#8212; in this case int &#8212; to bool.</p>
<pre class="prettyprint lang-ml">val List.filter : ('T -&gt; bool) -&gt; 'T list -&gt; 'T list</pre>
<p>Now all types align and we&#8217;ve simplified the code a little. </p>
<p>PS: Partial function application is also possible in C# if you define functions using one of the <a href="http://msdn.microsoft.com/en-us/library/bb534960.aspx">Func&lt;T&gt;</a> or <a href="http://msdn.microsoft.com/en-us/library/018hxwa8.aspx">Action&lt;T&gt;</a> delegates.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2012/06/21/simplifying-f-lambda-expressions-with-partial-function-application/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>F# list immutability by example</title>
		<link>http://www.bugfree.dk/blog/2012/06/17/f-list-immutability-by-example/</link>
		<comments>http://www.bugfree.dk/blog/2012/06/17/f-list-immutability-by-example/#comments</comments>
		<pubDate>Sun, 17 Jun 2012 12:22:44 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[F#]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1094</guid>
		<description><![CDATA[The other day, I stumbled on Ivan Towlson&#8217;s A Practical Developer&#8217;s Introduction to F#. It&#8217;s one of the best introductions I&#8217;ve seen in a long time, simply because it&#8217;s so practically oriented. I learned a couple of things about F# from the video, which I’ll summarize in a couple of posts. The first thing I [...]]]></description>
			<content:encoded><![CDATA[<p>The other day, I stumbled on <a href="http://hestia.typepad.com/flatlander/">Ivan Towlson&#8217;s</a> <a href="http://channel9.msdn.com/Events/TechEd/NewZealand/2011/DEV311">A Practical Developer&#8217;s Introduction to F#</a>. It&#8217;s one of the best introductions I&#8217;ve seen in a long time, simply because it&#8217;s so practically oriented. I learned a couple of things about F# from the video, which I’ll summarize in a couple of posts.</p>
<p>The first thing I learned is how the F# list type, which is a linked list and not List&lt;T&gt;, is immutable for reasons of safety and efficiency. Once you create a list, you can never again modify this exact instance. If you do, what you&#8217;ll get back is a new list. Think of the safety in terms of threads: if one thread, inadvertently or not, modifies the list, it’ll just get back a new list, shielding any other thread from the change. </p>
<p>This copy-on-modification behavior may seem inefficient at first. And it would be if it weren’t for F#’s ability to share part of a list:</p>
<pre class="prettyprint lang-ml">let smallOddPrimes = [3; 5; 7]
let smallPrimes = 2 :: smallOddPrimes // [2; 3; 5; 7]</pre>
<p>When you create the smallPrimes list, F# need only create one additional cell containing the even prime. The next pointer of this cell will be a reference to the smallOddPrimes list:</p>
<pre class="prettyprint lang-ml">Object.ReferenceEquals(smallPrimes.Tail, smallOddPrimes) // true</pre>
<p>The tail of the smallPrimes list &#8212; the possibly empty list comprised of everything but the first element &#8212; points back to smallOddPrimes list, saving both processing time and memory while retaining thread-safety.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2012/06/17/f-list-immutability-by-example/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automating SharePoint 2010 build and deployment with PowerShell and PSake</title>
		<link>http://www.bugfree.dk/blog/2012/06/10/automating-sharepoint-2010-build-and-deployment-with-powershell-and-psake/</link>
		<comments>http://www.bugfree.dk/blog/2012/06/10/automating-sharepoint-2010-build-and-deployment-with-powershell-and-psake/#comments</comments>
		<pubDate>Sun, 10 Jun 2012 11:56:00 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Process]]></category>
		<category><![CDATA[Productivity]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1090</guid>
		<description><![CDATA[A while ago I blogged about what I considered essential requirements for a developer automation tool. I proposed abandoning batch files in favor of more powerful automation tools and using these tools all the way from development to production. In the time passed, PowerShell has only become more ubiquitous, and with SharePoint 2010 adding 570 [...]]]></description>
			<content:encoded><![CDATA[<p>A while ago I blogged about what I considered <a href="http://www.bugfree.dk/blog/2010/09/26/essential-requirements-for-a-developer-automation-tool/">essential requirements for a developer automation tool</a>. I proposed abandoning batch files in favor of more powerful automation tools and using these tools all the way from development to production. In the time passed, PowerShell has only become more ubiquitous, and with SharePoint 2010 adding 570 cmdlets on top of the 240 existing ones, building and deploying SharePoint with PowerShell makes a lot of sense.</p>
<p>Before diving into the details of how PowerShell can be used to build and deploy a SharePoint solution, I quickly want to cover some of the downsides as well: the PowerShell environment and the SharePoint cmdlets add additional plumping on top of something that’s already very complex. If you&#8217;re already well-versed in the SharePoint .NET APIs, the added (accidental) complexity may not be worth it. The good-old console application in which you’re already familiar with the syntax, semantics, and debugging procedures hasn’t been obsoleted by PowerShell.</p>
<h4>Getting started with PSake</h4>
<p>Nothing prevents you from automating using plain PowerShell, but leaning on an open source module like <a href="http://en.wikipedia.org/wiki/Psake">PSake</a> will relieve you from writing tedious plumping code. PSake is an <a href="http://martinfowler.com/bliki/DomainSpecificLanguage.html">internal DSL</a> for defining, among other things, tasks and interdependencies between these. It then determines a proper task execution order and does error detection while it executes each task. PSake also comes with a handy external command-wrapper to be used within tasks which determines failure based on the exit code of the external process.</p>
<p>To get started with PSake, all you need is to go to the <a href="https://github.com/psake/psake">PSake Github repository</a> and download <a href="https://github.com/psake/psake/blob/master/psake.ps1">psake.ps1</a> and <a href="https://github.com/psake/psake/blob/master/psake.psm1">psake.psm1</a> to a local folder. I usually place these in the root of my source folder, next to the solution file. psake.ps1 is a wrapper that enables you to open a PowerShell console and execute a PSake task without first having to load the PSake module. The wrapper will simply load the module and pass along any command-line arguments to PSake.</p>
<p>Keep in mind that PSake <a href="http://groups.google.com/group/psake-users/browse_thread/thread/8ee0a4cb117a6412">isn’t designed with nested scripts in mind</a>. It’s possible to have a master PSake script call out to child PSake scripts, but an error in a child will not get propagated to the master, causing the master to continue on error. Tasks should therefore be collected in a single file, possibly named default.ps1, which is what PSake looks for by default.</p>
<h4>PSake script organization</h4>
<p>The script organization outlined in this section is backed by snippet-like examples from one of my build files. Don’t focus on the PowerShell specifics in these examples, but instead on the overall organization and purpose of each section.</p>
<p>Every one of my PSake scripts start out with global definitions at the top. These are used throughout the script and conceptually serve as common hidden arguments to the tasks. PSake also comes with a Properties block for making variables available to tasks, but I don’t think it adds significant value over plain script definitions.</p>
<pre class="prettyprint">$base_dir = resolve-path .
$sln_file = "$base_dir\$acme.sln"
$build_configuration = "debug"
$acme = "Acme.Intranet"
$msbuild_exe = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe"
$wsp_projs = @("Branding", "Records")
$other_projs = @("Console")
$current_user = "$env:userdomain\$env:username"
$web_application_name = "Acme"
...</pre>
<p>Next come any PowerShell function used by other functions or tasks. These functions will usually extend the capabilities of existing cmdlets by composition or/and calling out to .NET APIs directly. I strive to make these function build script-independent by parameterization. To limit side effects and simplify debugging, the functions should rely solely on the arguments being passed, and refrain from accessing any global variable.</p>
<p>Here I load the Microsoft.SharePoint.dll but the types of any .NET assembly can be made available to the script this way. </p>
<pre class="prettyprint">[Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") | out-null

function RemoveBuildFolders([string]$source_dir) { 
  ("bin", "obj", "pkg", "pkgobj") | foreach {
    $path = "$source_dir\$_"
    if (test-path $path) {
      remove-item $path -confirm:$false -recurse -force
    }
  }
}

function IsUserAdministrator() { ... }
function ImportTermSetFromFile([string]$filePath, [string]$groupName) { ... }
function WaitForTimerJobToFinish([string]$solutionFileName) { ... }
...</pre>
<p>For the script to use any of the SharePoint cmdlets, you must first load the SharePoint PowerShell snapin. The loading of this snapin is actually what differentiates the SharePoint 2010 Management Shell from the regular PowerShell &#8212; the former launches PowerShell and executes a script that loads the snapin. For some reason, however, it’s necessary to unload/load the snapin every time the script executes or the SharePoint cmdlets will only be available the first time around. Hence this code needs to be placed outside of any function, causing it to execute immediately.</p>
<pre class="prettyprint">$name = "Microsoft.SharePoint.PowerShell"
$snapin = get-pssnapin | where { $_.name -eq $name }
if ($snapin -ne $null) {
  remove-pssnapin $name
}
add-pssnapin $name</pre>
<p>Now we’re ready to define the actual tasks. Depending on your SharePoint solution, you may want to distribute the responsibility among the tasks differently, but build and deployment will likely assume this overall form:</p>
<pre class="prettyprint">task Install -depends Clean, Compile, CreateWebApplication, CreateSiteCollection,
                      ActivateSiteCollectionFeatures, CreateSites, PreInstall,
                      InstallWsps, ActivateSiteFeatures, PostInstall

task Uninstall -depends DeactivateSiteFeatures, RemoveSites, DeactivateSiteCollectionFeatures,
                        RemoveSiteCollection, UninstallWsps, RemoveWebApplication</pre>
<p>The Compile task, for instance, calls out to MSBuild just like Visual Studio does. This has the nice benefit that the build script will automatically use build settings defined in Visual Studio as they’re stored in the MSBuild project file. Note also how WSPs are created by invoking the package target of a SharePoint project file. Again, all the package specific settings of Visual Studio will carry over seamlessly.</p>
<pre class="prettyprint">task Compile {
  exec { &amp; "$msbuild_exe" "/p:configuration=$build_configuration" "$sln_file" }
  $wsp_projs | foreach {
    $proj_file = "$base_dir\$acme.$_\$acme.$_.csproj"
    exec { &amp; "$msbuild_exe" "/p:configuration=$build_configuration" "$proj_file" "/t:package" }
  }
}</pre>
<p>The ActivateSiteCollectionFeatures task illustrates the SharePoint cmdlets in action. It also shows how to spawn a new PowerShell console to avoid a “The trial period for this product has expired” error when activating the PublishingSite feature. This error seems to be related to stale state (a bug) within the current PowerShell session as I’m not running a trial version of SharePoint. On a similar note, one of my scripts activate the Nintex Workflow 2010 features. This operation will fail if you use the enable-spfeature cmdlet instead of stsadm, alluding to another bug in the PowerShell/SharePoint integration.</p>
<pre class="prettyprint">task ActivateSiteCollectionFeatures {
  install-spfeature PublishingSite
  
  # work around the 'The trial period for this product has expired.' error
  exec { powershell -command "add-pssnapin microsoft.sharepoint.powershell; 
                              enable-spfeature -identity PublishingSite -url $site_collection_url" } 

  enable-spfeature -identity OfficeWebApps -url $site_collection_url
  enable-spfeature -identity PremiumSite -url $site_collection_url
  ...
}</pre>
<p>Assuming a complete script, here’s how you’d invoke the Install task in a script named default.ps1.</p>
<pre class="prettyprint">.\psake.ps1 .\default.ps1 Install</pre>
<p>This&#8217;ll execute the Install task, recursively executing its dependencies.</p>
<h4>Observations</h4>
<p>Automating SharePoint build and deployment is challenging. At times SharePoint will exhibit non-deterministic behavior, succeeding or failing by random. For instance, even though you explicitly deactivate and uninstall a feature, during installation the script may fail telling you the feature is already activated. You could add a “continue on error” flag to problematic cmdlets, but this would also prevent error detection, and you’ll likely end up with cascade failures later or functionality you can’t trust being correctly build and deployed. Adding error recovery and correction code at select places is probably a better choice.</p>
<p><a href="http://stackoverflow.com/questions/795751/can-i-get-detailed-exception-stacktrace-in-powershell">Debugging a large PowerShell script</a> can be time consuming. With <a href="http://powergui.org">PowerGUI</a> or a similar environment you’re able to set breakpoints, but simple print-lining and writing out the value of $errors[0] will usually suffice. The $errors collection is a circular buffer of the most recent script errors encountered. You can also modify the trace level within the special TaskSetup and TaskTearDown tasks that execute before and after any of your tasks.</p>
<pre class="prettyprint">TaskSetup { Set-PSDebug -trace 1 }
TaskTearDown { Set-PSDebug -trace 0 }</pre>
<p>This’ll emit a lot of trace output which may also be useful to include in a build log.</p>
<h4>Conclusion</h4>
<p>I think there’s some merit to the argument of not relying solely on PowerShell for complex SharePoint build and deployment. Don’t get me wrong, PowerShell is a very nice scripting language and there’s very little PowerShell can’t do from a purely technical perspective. The dynamic nature of PowerShell, however, makes it less suited for longer and complex scripts.</p>
<p>My latest SharePoint build and deployment script is approaching 700 lines of PowerShell code and contains some <a href="http://www.bugfree.dk/blog/2011/11/27/importing-csv-term-sets-into-sharepoint-2010-using-powershell/">fairly complex functions</a> that should probably have been <a href="http://www.bugfree.dk/blog/2012/05/20/importing-csv-term-sets-into-sharepoint-2010-using-f/">written in a non-scripting language</a> and exposed to PowerShell through something like a <a href="http://www.bugfree.dk/blog/2011/11/23/using-a-generic-command-line-runner-for-utility-tasks/">generic command-line runner</a>. You could also have created custom cmdlets, but why tie your code unnecessarily to PowerShell?</p>
<p>For additional inspiration on how to organize your build scripts, <a href="http://www.pseale.com/blog/StealIdeasFromThesePsakeScripts.aspx">a number of</a> prominent open source projects use PSake, most notably <a href="https://github.com/NServiceBus/NServiceBus">NServiceBus</a> and <a href="https://github.com/ravendb/ravendb">RavenDB</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2012/06/10/automating-sharepoint-2010-build-and-deployment-with-powershell-and-psake/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Importing CSV term sets into SharePoint 2010 using F#</title>
		<link>http://www.bugfree.dk/blog/2012/05/20/importing-csv-term-sets-into-sharepoint-2010-using-f/</link>
		<comments>http://www.bugfree.dk/blog/2012/05/20/importing-csv-term-sets-into-sharepoint-2010-using-f/#comments</comments>
		<pubDate>Sun, 20 May 2012 15:10:26 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[F#]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1086</guid>
		<description><![CDATA[Source code available through Github. See also: Importing CSV term sets into SharePoint 2010 using PowerShell. Here I provide an F# implementation of a Powershell script for populating the SharePoint 2010 term store with a term set. Each term set is stored in a CSV file (whose format is defined by Microsoft) that drives the [...]]]></description>
			<content:encoded><![CDATA[<p>Source code <a href="https://github.com/ronnieholm/Bugfree.SharePoint">available</a> through Github.    <br />See also: <a href="http://www.bugfree.dk/blog/2011/11/27/importing-csv-term-sets-into-sharepoint-2010-using-powershell/">Importing CSV term sets into SharePoint 2010 using PowerShell</a>.</p>
<p>Here I provide an F# implementation of a <a href="http://www.bugfree.dk/blog/2011/11/27/importing-csv-term-sets-into-sharepoint-2010-using-powershell/">Powershell script</a> for populating the SharePoint 2010 term store with a term set. Each term set is stored in a CSV file (whose format is defined by Microsoft) that drives the calls made to the SharePoint .NET APIs to import it:</p>
<pre class="prettyprint lang-none">|   |       0       |       5      |       6      | ... |      11      |
|---|---------------|--------------|--------------|-----|--------------|
| 0 | Term Set Name | Level 1 Term | Level 2 Term | ... | Level 7 Term |
| 1 | TermSetName   |              |              | ... |              |
| 2 |               | Term1        |              | ... |              |
| 3 |               | Term2        | Term2.2      | ... |              |</pre>
<p>Once the term set has been imported, this is what the hierarchy looks like from within SharePoint:</p>
<p><a href="http://www.bugfree.dk/blog/wp-content/uploads/2012/05/TermStore1.png"><img style="background-image: none; border-right-width: 0px; margin: 3px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="TermStore[1]" border="0" alt="TermStore[1]" src="http://www.bugfree.dk/blog/wp-content/uploads/2012/05/TermStore1_thumb.png" width="216" height="148" /></a></p>
<p>First the function signatures:</p>
<pre class="prettyprint lang-ml">// Program.fsi
module Bugfree.SharePoint.TermSetImporter

open Microsoft.SharePoint.Taxonomy

val importCsv : string -&gt; seq&lt;string[]&gt;
val removeTermGroup : TermStore -&gt; string -&gt; unit
val getOrCreate : 'b -&gt; seq&lt;'a&gt; -&gt; ('a -&gt; bool) -&gt; ('b -&gt; 'a) -&gt; 'a
val getOrCreateGroup : string -&gt; TermStore -&gt; Group
val getOrCreateSet : string -&gt; Group -&gt; TermSet
val getOrCreateTerm : string -&gt; TermSetItem -&gt; Term
val importTerm : TermSetItem -&gt; string list -&gt; TermSetItem
val importTermSet : TermStore -&gt; string -&gt; seq&lt;string[]&gt; -&gt; unit 
val main : string[] -&gt; int</pre>
<p>Then the implementation:</p>
<pre class="prettyprint lang-ml">// Program.fs
module Bugfree.SharePoint.TermSetImporter

open System.IO
open System.Collections.Generic
open Microsoft.SharePoint
open Microsoft.SharePoint.Taxonomy

let importCsv path =
    seq { use sr = File.OpenText(path)
          while not sr.EndOfStream do                  
            let line = sr.ReadLine()                  
            let tokens = line.Split [|','|]                  
            yield tokens }

let removeTermGroup (store : TermStore) name =
    store.Groups |&gt; Seq.filter(fun g -&gt; g.Name = name) 
                 |&gt; Seq.iter(fun g -&gt; g.TermSets |&gt; Seq.iter(fun t -&gt; t.Delete())
                                      g.Delete()
                                      store.CommitAll())

let getOrCreate name children predicate create =   
    match (Seq.tryFind predicate children) with
    | Some c -&gt; c
    | None -&gt; create name

let getOrCreateGroup name (store : TermStore) =
    getOrCreate name store.Groups (fun g -&gt; g.Name = name) 
                                  (fun name -&gt; store.CreateGroup(name))

let getOrCreateSet name (group : Group) =
    getOrCreate name group.TermSets (fun s -&gt; s.Name = name) 
                                    (fun name -&gt; group.CreateTermSet(name))

let getOrCreateTerm name (item : TermSetItem) =
    getOrCreate name item.Terms (fun t -&gt; t.Name = name) 
                                (fun name -&gt; item.CreateTerm(name, 1033))

let rec importTerm (parent : TermSetItem) levels =       
    match levels with
    | [] -&gt; parent
    | head::tail -&gt; let t = getOrCreateTerm head parent
                    importTerm t tail
                               
let importTermSet (store : TermStore) groupName (rows : seq&lt;string[]&gt;) =  
    let termSetName = (rows |&gt; Seq.nth 1).[0].Replace(&quot;\&quot;&quot;, &quot;&quot;)
    let termSet = getOrCreateGroup groupName store |&gt; getOrCreateSet termSetName
    
    rows |&gt; Seq.skip 2 
         |&gt; Seq.iter(fun r -&gt; r.[5..] |&gt; Array.filter(fun i -&gt; i &lt;&gt; &quot;&quot;) 
                                      |&gt; Array.map(fun i -&gt; i.Replace(&quot;\&quot;&quot;, &quot;&quot;))
                                      |&gt; Array.toList
                                      |&gt; importTerm termSet
                                      |&gt; ignore)
    store.CommitAll()

[&lt;EntryPoint&gt;]
let main args =
    let siteCollection = new SPSite(&quot;http://sp2010&quot;)
    let session = new TaxonomySession(siteCollection)
    let store = session.TermStores.[&quot;Managed Metadata Service&quot;]    
    let rows = importCsv &quot;C:\Test.csv&quot;
    let groupName = &quot;MyGroup&quot;
    removeTermGroup store groupName
    importTermSet store groupName rows
    0</pre>
<p>Maybe it’s implementing the population algorithm twice, but to me the F# implementation seems the easiest one to implement and follow. Not because PowerShell is a bad language, but because F#’s static typing and type inferencing makes it better suited for implementing something of this relative complexity.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2012/05/20/importing-csv-term-sets-into-sharepoint-2010-using-f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Downloading RSS enclosures with PowerShell</title>
		<link>http://www.bugfree.dk/blog/2012/04/21/downloading-rss-enclosures-with-powershell/</link>
		<comments>http://www.bugfree.dk/blog/2012/04/21/downloading-rss-enclosures-with-powershell/#comments</comments>
		<pubDate>Sat, 21 Apr 2012 19:35:16 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Powershell]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1085</guid>
		<description><![CDATA[Say you subscribe to a number of podcasts and would like new episodes to be downloaded and put in a special folder as they become available. You could go and inspect the URLs to the episodes and see if there’s a pattern and then periodically scan for new files. A better alternative, though, would be [...]]]></description>
			<content:encoded><![CDATA[<p>Say you subscribe to a number of podcasts and would like new episodes to be downloaded and put in a special folder as they become available. You could go and inspect the URLs to the episodes and see if there’s a pattern and then periodically scan for new files. A better alternative, though, would be to extract the URLs from the RSS feed, an XML file organized as follows:</p>
<ul>
<li>rss
<ul>
<li>channel
<ul>
<li>title </li>
<li>link </li>
<li>description </li>
<li>… </li>
<li>item
<ul>
<li>title </li>
<li>link </li>
<li>pubdate </li>
<li>enclosure
<ul>
<li>url </li>
<li>… </li>
</ul>
</li>
<li>… </li>
</ul>
</li>
<li>… </li>
</ul>
</li>
</ul>
</li>
</ul>
<p>Assuming the feed points to a blog, the initial channel tags would hold general information about the blog and each item would represent a blog post. Files would be associated with posts through the enclosure tag and this is how you’d download episodes. Using PowerShell to parse the XML file, it’s fairly straightforward to download either the most recent enclosures or all episodes.</p>
<pre class="prettyprint">function Get-RssEnclosures([String]$rssUrl, 
                           [DateTime]$moreRecentThan, 
                           [String]$destinationFolder) {
  # directory where WebClient will download files to
  [Environment]::CurrentDirectory = $destinationFolder 

  $feed = [xml](new-object Net.WebClient).DownloadString($rssUrl)
  $feed.rss.channel.item | foreach {
    $enclosureUrl = $_.enclosure.url    
    
    # some feeds I download contain empty enclosure urls
    if ($enclosureUrl -ne "") {
      $enclosureUrl = new-object Uri($enclosureUrl)
      $filename = $enclosureUrl.Segments[-1]
      
      # some items I download have non-parsable 'EDT' as part of pubdate 
      $pubDate = [DateTime]::Parse($_.pubdate.Replace("EDT", ""))

      if (($pubDate -ge $moreRecentThan) -and 
          (-not (test-path (join-path $destinationFolder $fileName)))) {
        (new-object Net.WebClient).DownloadFile($enclosureUrl, $filename)
      }
    }
  } 
}

@("http://feeds.feedburner.com/HanselminutesCompleteMP3",
  "http://www.pwop.com/feed.aspx?show=dotnetrocks&amp;filetype=master",
  "http://feeds.feedburner.com/DnrtvWmv",
  "http://thisdeveloperslife.com/rss",
  "http://feeds.feedburner.com/herdingcode",
  "http://feeds.feedburner.com/anugcast") | foreach {
  Get-RssEnclosures $_ ([DateTime]::Now.AddDays(-7)) "E:\Podcasts"
}</pre>
<p>The nice thing about PowerShell is that you can dot your way through the XML hierarchy and use regular .NET classes for date parsing and file download. Now you can setup this script to execute at regular intervals and go to the destination folder whenever you feel like listening to a podcast.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2012/04/21/downloading-rss-enclosures-with-powershell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Evaluating Business Connectivity Services in SharePoint 2010 for web service, read/write use</title>
		<link>http://www.bugfree.dk/blog/2012/04/08/evaluating-business-connectivity-services-in-sharepoint-2010-for-web-service-readwrite-use/</link>
		<comments>http://www.bugfree.dk/blog/2012/04/08/evaluating-business-connectivity-services-in-sharepoint-2010-for-web-service-readwrite-use/#comments</comments>
		<pubDate>Sun, 08 Apr 2012 15:01:43 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1081</guid>
		<description><![CDATA[This post describes my first attempt, and the challenges I encountered, using BCS to expose and write back external data with SharePoint. Before BCS, I’d used regular SharePoint lists and associations, but over time my 20 lists outgrew SharePoint’s limited relational model. Hence I switched to MS SQL Server, added a web service on top, [...]]]></description>
			<content:encoded><![CDATA[<p>This post describes my first attempt, and the challenges I encountered, using BCS to expose and write back external data with SharePoint. Before BCS, I’d used regular SharePoint lists and associations, but over time my 20 lists outgrew SharePoint’s limited relational model. Hence I switched to MS SQL Server, added a web service on top, and began looking into BCS as a way to expose CRUD logic and support for different views on the data. Something that SharePoint excels at for regular lists.</p>
<p>At this point, I should probably point out that some of the pain I encountered may well be due to my lack of experience with the framework and tooling. In this case, feel free to drop me a note. I would also like to point out that my aim here is to highlight the significant issues I encountered. There’re already a lot of posts out there iterating the positive sides of BCS, but as a developer I’m equally, if not more, concerned with its limitations.</p>
<h4>The SharePoint Designer 2010 experience</h4>
<p>With the aid of SharePoint Designer 2010 (SPD), it’s a breeze to define an external content type to match the response of a web service and create an external list based on this content type. The ugly truth, though, is that although the external list will visually appear much like a standard SharePoint list, in terms of functionality it’s <a href="http://www.sharepointanalysthq.com/2010/07/bcs-external-list-limitations/">significantly impaired</a> (see also <a href="http://www.amazon.com/Inside-Microsoft-SharePoint-2010-Pattison/dp/0735627460/ref=sr_1_1?ie=UTF8&amp;qid=1333623874&amp;sr=8-1">Inside Microsoft SharePoint 2010</a>, page 493). In short, while BCS and SPD enables you get off the ground quickly, if you don’t understand their limitations, you may have incurred a significant <a href="http://en.wikipedia.org/wiki/Technical_debt">technical debt</a> from the get-go.</p>
<p>Behind the scenes, what SPD does is maintain an <a href="http://msdn.microsoft.com/en-us/library/ff798325.aspx">XML-based metadata model</a>, mapping a set of method stereotypes, such as Finder, SpecificFinder, Insert, Update, and Delete to actual methods on the web service. For BCS to work, these methods must satisfy a rigid set of requirements concerning their signature and behavior. When SharePoint, through the BCS runtime, needs to interact with the external system, BCS will look up the specific method to call within the model and process the result accordingly.</p>
<p>Interestingly, while SPD may be a good starting point for creating the model, the model is actually richer than SPD is able to express. Oftentimes you need to go beyond SPD and export the model, edit the XML file by hand, and then import it back into SharePoint. Your modifications will mostly be left alone by SPD, though not always. Take field ordering within a content type for example: whenever you edit the content type, the order seems to get reset to the order in which .NET reflects over the <a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datamemberattribute.aspx">DataMember</a>s of the <a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx">DataContract</a> within the generated web service proxy. This in turn affects the order in which form fields appear on the generated display, new, and edit forms. The DataMember attribute actually has an <a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datamemberattribute.order.aspx">Order</a> property but since it has no effect on the generated WSDL, SPD can’t possibly take it into account. The net effect is that you’ll oftentimes have to go edit the XML file by hand or script the it.</p>
<p>When creating an external list based on a content types, the display, edit, and new forms are generated from the model. But how are future changes to the model propagated to existing forms? It turns out some are carried over automatically (see <a href="http://www.amazon.com/Professional-Business-Connectivity-SharePoint-Programmer/dp/047061790X/ref=sr_1_1?ie=UTF8&amp;qid=1333627074&amp;sr=8-1">Professional Business Connectivity Services in SharePoint 2010</a>, page 55), whereas others will require the list to be re-generated. Not the ideal choice if your end-users made any modifications that needs to be preserved. It seems difficult, bordering impossible, to modify the generated ASPX forms, except through hacks with JavaScript, in which case InfoPath is probably the better choice. I wouldn’t want to use InfoPath for a 20 lists solution, though. Using InfoPath on this scale quickly becomes tedious, error-phone, and not maintainable in the long run.</p>
<p>In my opinion, the process of defining content types with SPD doesn’t scale. Once you go beyond a few content types, working with SPD becomes tedious. When your data source is a web service, the list of methods on it required just to make CRUD operations work makes the contract quite large. Up to more than 100 methods for my 20 content types, and except for the stereotypical Finder method, none of these support bulk operations. As SPD has to retrieve the contract and generate a proxy from it, not to mention manipulate the model stored within the BCS Service Application, the UI isn’t particularly responsive. The SPD UI itself seems to have been optimized for working with only a few read-only external content types within a solution. You can’t specify field ordering or which field control to use for rendering or editing a field, and it’s sometimes hard to locate your web method amongst the 100+ candidates.</p>
<h4>The SharePoint end-user experience</h4>
<p>External content types are made up of fields whose types are a subset of the primitive types of .NET. For each such .NET type, a rudimentary mapping to SharePoint’s field controls exists, describing a field’s visual appearance. Fields of type string for instance will, on the new and edit forms, render as a single-line text field. With regular lists, using the browser interface, you can easily turn a string field into a multi-line text area or a Rich Text field, but not so with external lists. At least not unless your forms are InfoPath-based. For ASPX forms, the .NET DateTime type, on the other hand, will render as the standard SharePoint date/time picker, allowing you to set date and time, but not easily only the date.</p>
<p>What I’m particularly missing is the People Picker. Within my database a number of fields store a domain\username provided by the user. These fields are of type string within the database and web service, so SPD will render these as single-line text field without the usual validator button. BCS does offer the ability to render custom <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfield.aspx">SPField</a>s by hand-tweaking the model (see <a href="http://www.amazon.com/Professional-Business-Connectivity-SharePoint-Programmer/dp/047061790X/ref=sr_1_1?ie=UTF8&amp;qid=1333627074&amp;sr=8-1">Professional Business Connectivity Services in SharePoint 2010</a>, page 174) and you may be able to use this approach to get the People Picker to render. Another alternative would be to alter the visual appearance and logic of the generated forms with JavaScript, although this seems like a brittle hack.</p>
<p>While on the subject of picker controls, the <a href="http://blogs.msdn.com/b/bcs/archive/2009/11/19/the-notion-of-associations-and-the-external-item-picker.aspx">external item picker</a> is used to setup one-to-many associations between external lists. To make the picker show up, you need to add of a lookup method to your web service and provide a stereotypical mapping to it. I mention this picker because it makes SharePoint display the associated item’s friendlier title instead of its foreign key identifier on the new and edit forms. Back on the list view, however, SharePoint will keep displaying the foreign key identifier, forcing end-users to have to lookup the meaning of it themselves. Moving on to many-to-many associations, they’re simply not supported by the user interface. You’d have to build a custom control for setting up the association or directly expose the junction table to end-users. But remember how list views can’t display the title of foreign items? The list view will end up showing rows of foreign key identifiers.</p>
<p>In my opinion, SharePoint does a decent job at presenting external data in read-only form but is severely lacking when it comes to editing. Creating a decent data entry experience is too much work compared to using an established technology such as ASP.NET. Sure, you could go with InfoPath, but it comes with its own set of peculiarities.</p>
<h4>Conclusion</h4>
<p>My 20 external content types turn into a metadata model of roughly 8,000 lines of XML with a huge blob at the top, storing the MSIL of the service proxy generated by SPD. You can think of this model as an XML representation of 20 <a href="http://en.wikipedia.org/wiki/Vtable">vtable</a>s, enriched with attributes to support form generation. All in all, a very complex setup for what it actually brings to the table. As a technology, I believe BCS to be too immature for intermediate to complex web service-based, read/write solutions &#8212; and I don’t want to create a code-based model using the BCS templates that ship with SharePoint for Visual Studio. In this case I’d rather go with an ASP.NET solution and embed it into SharePoint. I’d probably also skip the web service altogether and use a data access assembly instead.</p>
<p>But for the sake of the argument, let’s say BCS is still your tool of choice and that your solution warrants the creation of a significant number of external content types/external lists/forms. Then you should probably roll your own tools to either create the XML of the model directly or use the BCS object model to create the model and then export it. This way, you’ll have more control over field ordering and the like and be less dependent on SPD.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2012/04/08/evaluating-business-connectivity-services-in-sharepoint-2010-for-web-service-readwrite-use/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Version control strategies for relational database content</title>
		<link>http://www.bugfree.dk/blog/2012/03/02/version-control-strategies-for-relational-database-content/</link>
		<comments>http://www.bugfree.dk/blog/2012/03/02/version-control-strategies-for-relational-database-content/#comments</comments>
		<pubDate>Fri, 02 Mar 2012 12:45:28 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1079</guid>
		<description><![CDATA[I recently had to design a relational database in which content had to be versioned. Changes to more of less every record in every table in the database must be tracked. For just about any record, a user should be able to retrieve a report detailing the list of changes made to it, when they [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had to design a relational database in which content had to be versioned. Changes to more of less every record in every table in the database must be tracked. For just about any record, a user should be able to retrieve a report detailing the list of changes made to it, when they were made, and by whom.</p>
<p>I considered a few strategies for how to implement these requirements:</p>
<ol>
<li><strong>Use one table and clone rows before change</strong>. Every time a record is modified, a copy of it is made beforehand. I use the Active attribute of a record to denote which records are active vs. which make up the history. This approach, however, requires that you make the primary key a combination of Id and VersionId columns. Likewise, for relationships between tables, you must make the foreign key be a combination of ForeignId and ForeignVersionId. Referential integrity now becomes relatively straightforward to maintain, but the table may grow large and may likely contain a lot redundant information. </li>
<li><strong>Create one history table for each source table</strong>. A variation of #1 where each source table would have en corresponding history table with a close to identical schema, but with its own primary key. While this ensures that the source table only contains current rows, it effectively doubles the number of tables. Not to mention that every structural change to the source table would have to be propagated to the history table. </li>
<li><strong>Create a generic and conceptually separate history database</strong>. This approach consists of a history table serving any number of source tables. Conceptually, it’s a audit trail database of its own that the rest of the database need not know about. Each row in this history table would hold before and after values for changed columns only. You may even take it so far as to start with an empty source and a some history and replay every change made to the source up to some point in time. It would require special care to be taken for non-additive schema changes. </li>
</ol>
<p>I decided to go with the third option. To make it concrete, say I have a Contacts table. Besides the primary key, I store the name of the contact and possibly a comment:</p>
<pre class="prettyprint">CREATE TABLE [dbo].[Contacts](
  [Id] [int] IDENTITY(1,1) NOT NULL,
  [Name] [nvarchar](255) NOT NULL,
  [Comment] [nvarchar](max) NULL,
  [CreatedBy] [nvarchar](30) NOT NULL,
  [CreatedAt] [datetime] NOT NULL,
  [ModifiedBy] [nvarchar](30) NOT NULL,
  [ModifiedAt] [datetime] NOT NULL,
  [UniqueRowGuid] [uniqueidentifier] NOT NULL,
  [Active] [bit] NOT NULL)</pre>
<p>The remaining fields are system fields that I add to almost every table in the database. You could argue that the created and modified columns should really be part of the history table, but I prefer for the source table to be self-contained. UniqueRowGuid provides a unique identity of any row in any table and is useful for creating weak relationships between tables in the same database or across databases.</p>
<p>If it weren’t for the fact that a primary key of type Guid makes for bad clustered index performance, I could’ve made the primary key in every table be the UniqueRowGuid &#8212; MS SQL Server even has a special type of sequential Guid for this very purpose. But I stuck with the traditional integer-based key. The Active column is used to denote if a row has been deleted. I want to keep every row for some period of time, even though to the user it appears to have been deleted.</p>
<p>Jumping straight to the history schema, here’s what I decided to store for each change.</p>
<pre class="prettyprint">CREATE TABLE [dbo].[History](
  [Id] [int] IDENTITY(1,1) NOT NULL,
  [ChangeCorrelationGuid] [uniqueidentifier] NOT NULL,
  [UniqueRowGuid] [uniqueidentifier] NOT NULL,
  [ColumnName] [nvarchar](255) NOT NULL,
  [BeforeValue] [nvarchar](max) NOT NULL,
  [AfterValue] [nvarchar](max) NOT NULL,
  [CreatedAt] [datetime] NOT NULL,
  [Comment] [nvarchar](max) NULL)</pre>
<p>The ChangeCorrelationGuid allows for a grouping of related history entries. Suppose in one transaction you modified both the Name and Comment of a contact. Using this ChangeCorrelationGuid, you effectively create different versions of the row. Next comes the UniqueRowGuid which contains the row-value from the source table, resulting in a loose coupling between History and Contacts. Think of it as identifying the source row whereas ColumnName identifying the source column.</p>
<p>Strictly speaking, I don’t need to store both the BeforeValue and an AfterValue, since the AfterValue of one change becomes the Before version of the next. But this piece of controlled redundency makes querying for the summary easier and less costly.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2012/03/02/version-control-strategies-for-relational-database-content/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Importing CSV term sets into SharePoint 2010 using PowerShell</title>
		<link>http://www.bugfree.dk/blog/2011/11/27/importing-csv-term-sets-into-sharepoint-2010-using-powershell/</link>
		<comments>http://www.bugfree.dk/blog/2011/11/27/importing-csv-term-sets-into-sharepoint-2010-using-powershell/#comments</comments>
		<pubDate>Sun, 27 Nov 2011 22:55:00 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Powershell]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1078</guid>
		<description><![CDATA[See also: Importing CSV term sets into SharePoint 2010 using F# One of the new features of SharePoint 2010 is the ability to tag content using terms from a term store. The out of the box tooling for importing, exporting, and maintaining term stores is somewhat limited though. That’s why I created a PowerShell script [...]]]></description>
			<content:encoded><![CDATA[<p>See also: <a href="http://www.bugfree.dk/blog/2012/05/20/importing-csv-term-sets-into-sharepoint-2010-using-f/">Importing CSV term sets into SharePoint 2010 using F#</a></p>
<p>One of the new features of SharePoint 2010 is the ability to tag content using terms from a term store. The out of the box tooling for importing, exporting, and maintaining term stores is somewhat limited though. That’s why I created a PowerShell script to import term sets into the term store.</p>
<h4>Term store overview</h4>
<p>SharePoint organizes terms in either a taxonomy or a folksonomy. In a taxonomy, terms are organized hierarchically whereas in a folksonomy the structure is flat. A taxonomy or folksonomy is either global, making it available to all site collections within a web application that’s associated with a Managed Metadata Service, or local, making it available in one site collection only.</p>
<p>Multiple Managed Metadata Services may be associated with a web application or site collection, each service in turn responsible for a single term store. Within one term store, multiple groups may be created, each potentially storing multiple term sets. Finally, a term set may have terms nested up to seven levels deep:</p>
<pre>Managed Metadata Service Application
  TermStore
    Group1
      TermSet1
        Term1
          Term1.2
            Term1.2.3
              Term1.2.3.4
                Term1.2.3.4.5
                  Term1.2.3.4.5.6
                    Term1.2.3.4.5.6.7</pre>
<p>You manage the term store through the browser and its Term Store Management Tool (the _layouts/termstoremanager.aspx application page) or through the SharePoint API. The management tool supports importing term sets only from a <a href="http://technet.microsoft.com/en-us/library/ee424396.aspx">special CSV file format</a>&#160; (_layouts/1033/ImportTermSet.csv holds a sample) with these columns:</p>
<pre>Term Set Name
Term Set Description
LCID
Available for Tagging
Term Description
Level 1 Term
Level 2 Term
...
Level 7 Term</pre>
<p>The CSV file is incomplete in terms of what the term store offers. It doesn’t offer columns for specifying translations and synonyms for terms. But users can use <a href="http://www.wictorwilen.se/">Wictor Wilén</a>&#160;<a href="http://www.wictorwilen.se/Post/Create-SharePoint-2010-Managed-Metadata-with-Excel-2010.aspx">Excel sheet</a> to maintain the basic information. It has the standard columns above and includes macros to simplify saving in the correct format and creating additional term sets.</p>
<p>The question remains: do you maintain compatibility with the existing CSV format so you can import term sets using the browser or a forms-based tool like the <a href="http://termsetimporter.codeplex.com/">CSV Bulk Taxonomy Importer/Exporter</a>? Or do you define your own, possibly XML based format since term sets are hierarchical by nature, with additional columns for translations and synonyms? A non-CSV based format may also be easier to process. If you want to pursue the latter approach, <a href="http://sharepointtales.wordpress.com/">Ben Robb</a> has <a href="http://sharepointtales.wordpress.com/2010/05/06/manipulating-the-terms-store-through-powershell/">created a PowerShell script</a> to import his XML format.</p>
<h4>Importing term sets using PowerShell</h4>
<p>I decided to stick with the CSV file format and create a PowerShell script that would allow me to import a term set using the command-line:</p>
<pre class="prettyprint">function ImportTermSet([Microsoft.SharePoint.Taxonomy.TermStore]$store, [string]$groupName, [PSCustomObject]$termSet) {  
  function ImportTerm([Microsoft.SharePoint.Taxonomy.Group]$group, 
                      [Microsoft.SharePoint.Taxonomy.TermSet]$set, 
                      [Microsoft.SharePoint.Taxonomy.Term]$parent, 
                      [string[]]$path) {       	
    if ($path.Length -eq 0) {
      return
    } elseif ($group -eq $null) {
      $group = $store.Groups | where { $_.Name -eq $path[0] }
      if ($group -eq $null) {
        $group = $store.CreateGroup($path[0])
      }
    } elseif ($set -eq $null) {
      $set = $group.TermSets | where { $_.Name -eq $path[0] }
      if ($set -eq $null) {
        $set = $group.CreateTermSet($path[0])
      }
    } else {
      $node = if ($parent -eq $null) { $set } else { $parent }
      $parent = $node.Terms | where { $_.Name -eq $path[0] }  	   
      if ($parent -eq $null) {
        $parent = $node.CreateTerm($path[0], 1033)
      } 
    }
    
    ImportTerm $group $set $parent $path[1..($path.Length)]					
  }
  
  function RemoveTermGroup([Microsoft.SharePoint.Taxonomy.TermStore]$store, [string]$groupName) {
    $group = $store.Groups | where { $_.Name -eq $groupName }
    if ($group -ne $null) {
      $group.TermSets | foreach { $_.Delete() }
      $group.Delete()
      $store.CommitAll()
    }
  }
  
  RemoveTermGroup $store $groupName
  $termSetName = $termSet[0]."Term Set Name"    
  $termSet | where { $_."Level 1 Term" -ne "" } | foreach {
    $path = @($groupName, $termSetName) + @(for ($i = 1; $i -le 7; $i++) { 
      $term = $_."Level $i Term"
        if ($term -eq "") {
          break
        } else {
          $term
        }
      }
    )
	
    ImportTerm -path $path
  }
}</pre>
<p>The way to use the ImportTermSet function is best illustrated with an example:</p>
<pre class="prettyprint">$session = Get-SPTaxonomySession -Site "http://localhost"
$store = $session.TermStores["Managed Metadata Service"]   
$termSet = Import-Csv "C:\Users\Ronnie\Desktop\ImportTermSet.csv"
ImportTermSet $store "MyGroup" $termSet
$store.CommitAll()</pre>
<p>In its current form the script ignores the Term Set Description, LCID, Available for Tagging, and Term Description columns from the CSV file. It would be possible to take these columns into account by passing them to ImportTerm as well. Instead of just removing the head of the list, you’d remove the number of items consumed by the current step before recursing.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2011/11/27/importing-csv-term-sets-into-sharepoint-2010-using-powershell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Expressing a domain specific language of propositions in F#</title>
		<link>http://www.bugfree.dk/blog/2011/11/25/expressing-a-domain-specific-language-of-propositions-in-f/</link>
		<comments>http://www.bugfree.dk/blog/2011/11/25/expressing-a-domain-specific-language-of-propositions-in-f/#comments</comments>
		<pubDate>Fri, 25 Nov 2011 21:23:00 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[F#]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1077</guid>
		<description><![CDATA[One aspect of many functional languages that’s always fascinated me is the ease with which you can express a recursive structure, such as a language, and have it evaluated. Suppose you want to define the grammar of a DSL of propositions, in F# you could do so using the discriminated union type: type Proposition = [...]]]></description>
			<content:encoded><![CDATA[<p>One aspect of many functional languages that’s always fascinated me is the ease with which you can express a recursive structure, such as a language, and have it evaluated. Suppose you want to define the grammar of a <a href="http://en.wikipedia.org/wiki/Domain-specific_language">DSL</a> of propositions, in F# you could do so using the discriminated union type:</p>
<pre class="prettyprint lang-ml">type Proposition =
    | True
    | And of Proposition * Proposition
    | Or of Proposition * Proposition
    | Not of Proposition</pre>
<p>In an object-oriented language like C#, this definition would be analogous to a hierarchy of classes. Proposition would be the base class of True, And, Or, and Not. Each would then have a constructor that accepts some number of arguments, e.g., the And constructor would accept a two-tuple, two propositions, making the Proposition type recursive. In C# you might even model the recursive relationship using the <a href="http://en.wikipedia.org/wiki/Composite_pattern">Composite pattern</a>.</p>
<p>In F#, an instance of the Proposition type may be created using a constructor syntax that resembles that of a function call:</p>
<pre class="prettyprint lang-ml">let p = And(Or(True, Not(True)), Not(Not(True)))</pre>
<p>Now, because of the recursive nature of the Proposition type, instances of it form a <a href="http://en.wikipedia.org/wiki/Parse_tree">parse tree</a>-like structure:</p>
<pre>                        And
                        /\
                       /  \
                      Or  Not 
                      /\    \
                     /  \    \
                  True  Not  Not
                          \    \
                           \    \ 
                          True  True</pre>
<p>Having a parse tree is not very useful in itself. What you need is some way to execute or evaluate it. Given the recursive nature of the grammar, it makes sense for the evaluator to be recursively defined as well. The evaluator would do pattern matching on the node type, deconstructing it into the parts needed to evaluate it. Since our language of propositions maps directly to the boolean operations of F#, it’s very simple to evaluate the parse tree:</p>
<pre class="prettyprint lang-ml">let rec eval (p: Proposition) =
    match p with
    | True -&gt; true
    | And(p1, p2) -&gt; eval p1 &amp;&amp; eval p2
    | Or (p1, p2) -&gt; eval p1 || eval p2
    | Not(p1) -&gt; not (eval p1)

let e = eval p // e : bool = true</pre>
<p>The features of F# used here allow for more complicated languages to be expressed and evaluated directly without the need for any <a href="http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form">Backus-Naur</a> form and <a href="http://en.wikipedia.org/wiki/Parser_generator">parser generator</a>.</p>
<p>PS: I&#8217;ve encountered <a href="https://gist.github.com/2934374#file_fsharp.ml">this gist</a> implementing a nice progression of the same idea with expressions and variables.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2011/11/25/expressing-a-domain-specific-language-of-propositions-in-f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using a generic command-line runner for utility tasks</title>
		<link>http://www.bugfree.dk/blog/2011/11/23/using-a-generic-command-line-runner-for-utility-tasks/</link>
		<comments>http://www.bugfree.dk/blog/2011/11/23/using-a-generic-command-line-runner-for-utility-tasks/#comments</comments>
		<pubDate>Wed, 23 Nov 2011 10:04:00 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1075</guid>
		<description><![CDATA[Most enterprise projects have one or more console applications for utility tasks such as cleaning up or importing data into the database. These utilities tend to be project-specific and small in terms of code size, and instead of several smaller assemblies, it makes sense to combine these into a single assembly. The generic runner would [...]]]></description>
			<content:encoded><![CDATA[<p>Most enterprise projects have one or more console applications for utility tasks such as cleaning up or importing data into the database. These utilities tend to be project-specific and small in terms of code size, and instead of several smaller assemblies, it makes sense to combine these into a single assembly. The generic runner would read the utility, called the command, and arguments from the command-line and use the <a href="http://en.wikipedia.org/wiki/Command_pattern">command pattern</a> to create and execute it.</p>
<p>For the generic runner to work, each command has to fulfill the contract.</p>
<pre class="prettyprint lang-cs">public enum ExitCode {
    Success = 0,
    Failure
};

public interface ICommand {
    string Usage { get; }
    string Description { get; }
    ExitCode Execute(string[] args);
}</pre>
<p>I want the runner to adhere to the <a href="http://en.wikipedia.org/wiki/Open/closed_principle">open/closed principle</a>. For its behavior to be modified without altering its core delegation logic. This requires the use of reflection to retrieve and instantiate a command based on command-line arguments.</p>
<pre class="prettyprint lang-cs">class Program {
    static IEnumerable&lt;ICommand&gt; GetCommands() {
        var iCommand = typeof (ICommand);
        return System.Reflection.Assembly.GetExecutingAssembly().GetTypes().ToList()
            .Where(t =&gt; iCommand.IsAssignableFrom(t) &amp;&amp; t != iCommand)
            .Select(t =&gt; Activator.CreateInstance(t) as ICommand);
    }

    static void DisplayHelp() {
        Console.WriteLine(&quot;Console [Command] [Arg1] [Arg2] [ArgN]\n\n&quot;);
        GetCommands().ToList().ForEach(command =&gt; 
            Console.WriteLine(command.Usage + &quot;\n&quot; + command.Description + &quot;\n\n&quot;));
    }

    static int Main(string[] args) {
        if (args.Length == 0) {
            DisplayHelp();
            return (int)ExitCode.Failure;
        }

        var commandName = args[0];
        var command = GetCommands().Where(t =&gt; t.GetType().Name == commandName).SingleOrDefault();
        if (command == null)
            throw new ArgumentException(string.Format(&quot;Command '{0}' not found&quot;, commandName));

        var executeArguments = new List&lt;string&gt;(args);
        executeArguments.RemoveAt(0);

        var exitCode = command.Execute(executeArguments.ToArray());
        return (int)exitCode;
    }
}</pre>
<p>A trivial example of a command that adds two numbers would be the following:</p>
<pre class="prettyprint lang-cs">// $&gt; GenericRunner.exe Calculator 2 3 =&gt; 2 + 3 = 5
public class Calculator : ICommand {
    public string Usage {
        get { return &quot;Calculator [Op1] [Op2]&quot;; }
    }

    public string Description {
        get { return &quot;World's simplest calculator&quot;; }
    }
        
    public ExitCode Execute(string[] args) {
        try {
            Console.WriteLine(
                string.Format(
                    &quot;{0} + {1} = {2}&quot;,
                    args[0], args[1], int.Parse(args[0]) + int.Parse(args[1])));
            return ExitCode.Success;
        } catch (Exception e) {
            Console.WriteLine(e.ToString());
            return ExitCode.Failure;
        }
    }
}</pre>
<p>Now multiple smaller assemblies can be grouped into one, with a description of all commands automatically being assembled, and without commands interfering (too much) with each other.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2011/11/23/using-a-generic-command-line-runner-for-utility-tasks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>F# + SharePoint = a list attachment versioning event receiver</title>
		<link>http://www.bugfree.dk/blog/2011/11/21/f-sharepoint-a-list-attachment-versioning-event-receiver/</link>
		<comments>http://www.bugfree.dk/blog/2011/11/21/f-sharepoint-a-list-attachment-versioning-event-receiver/#comments</comments>
		<pubDate>Mon, 21 Nov 2011 07:37:00 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[F#]]></category>
		<category><![CDATA[SharePoint]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1074</guid>
		<description><![CDATA[It’s been a while since I last took a serious look at F#. Back then I did a simple random fractal terrain generator which, even though the algorithm is simple, I found challenging to do. Nevertheless, functional programming is just one of those areas that I keep returning to. This time around I want to [...]]]></description>
			<content:encoded><![CDATA[<p>It’s been a while since I last took a serious look at F#. Back then I did a simple <a href="http://www.bugfree.dk/blog/2009/03/06/generating-2d-random-fractal-terrains-with-f/">random fractal terrain generator</a> which, even though the algorithm is simple, I found challenging to do. Nevertheless, functional programming is just one of those areas that I keep returning to. This time around I want to use the event receiver for <a href="http://www.bugfree.dk/blog/2011/11/17/versioning-attachments-in-a-sharepoint-list-using-snapshotting/">versioning attachments in SharePoint lists</a> to get familiar with object-oriented F#. Of course, translating a C# class to an F# class, the result will look like C# with different syntax and better type inference. The point here is to use classes in F# as a way to expose functionality to other .NET languages. In a real-world F# application the core logic would likely not be object-oriented.</p>
<pre class="prettyprint lang-ml">namespace Dk.Bugfree

open System
open System.Globalization
open Microsoft.SharePoint

type public ListAttachmentVersioningEventReceiver() =
    inherit SPItemEventReceiver()
    
    member private r.CustomVersion = &quot;CustomVersion&quot;
    member private r.ShadowLibrary = &quot;ShadowLibrary&quot;

    // override ItemAdded : properties:SPItemEventProperties -&gt; unit
    override r.ItemAdded properties =
        base.ItemAdded properties
        r.SetCustomVersionLabel properties.ListItem
        r.CreateSnapshot properties

    // override ItemUpdated : properties:SPItemEventProperties -&gt; unit
    override r.ItemUpdated properties =
        base.ItemUpdated properties
        let item = properties.ListItem

        if r.RollbackHappened item then
            r.RestoreSnapshot properties
            r.SetCustomVersionLabel item
            r.CreateSnapshot properties
        else
            r.CreateSnapshot properties
            r.SetCustomVersionLabel item

    // member private CreateSnapshot : properties:SPItemEventProperties -&gt; unit
    member private r.CreateSnapshot properties =
        use site = properties.OpenWeb()
        let item = properties.ListItem
        let shadowLibrary = site.Lists.[r.ShadowLibrary] :?&gt; SPDocumentLibrary
        let path = String.Format(&quot;Versions/{0}/{1}&quot;, item.ID, r.GetOfficialVersionLabel(item))
        let shadowFolder = r.CreateFolderPath shadowLibrary path
        
        item.Attachments |&gt; Seq.cast |&gt; Seq.iter (fun fileName -&gt;            
            let existingFile = item.ParentList.ParentWeb.GetFile(item.Attachments.UrlPrefix + fileName)
            let newFile = shadowFolder.Files.Add(fileName, existingFile.OpenBinaryStream())
            newFile.Item.Update())
    
    // member private RollbackHappened : item:SPListItem -&gt; bool
    member private r.RollbackHappened item =
        let culture = CultureInfo.InvariantCulture
        let currentVersion = Single.Parse(r.GetOfficialVersionLabel(item), culture)
        let lastVersion = Single.Parse(r.GetCustomVersionLabel(item), culture)
        currentVersion &gt; lastVersion + 1.0f

    // member private RestoreSnapshot : properties:SPItemEventProperties -&gt; unit
    member private r.RestoreSnapshot properties =
        let item = properties.ListItem
        let restoreVersion = r.GetCustomVersionLabel item
        r.EventFiringEnabled &lt;- false    

        item.Attachments |&gt; Seq.cast |&gt; Seq.map (fun fileName -&gt; unbox&lt;string&gt; fileName) |&gt; Seq.toList
                         |&gt; Seq.iter (fun fileName -&gt; item.Attachments.Delete(fileName))
        
        use site = properties.OpenWeb()
        let path = String.Format(&quot;Versions/{0}/{1}&quot;, item.ID, restoreVersion)
        let shadowLibrary = site.Lists.[r.ShadowLibrary] :?&gt; SPDocumentLibrary
        let source = r.CreateFolderPath shadowLibrary path

        source.Files |&gt; Seq.cast |&gt; Seq.iter (fun file -&gt;
            let unboxedFile = unbox&lt;SPFile&gt; file
            item.Attachments.Add(unboxedFile.Name, unboxedFile.OpenBinary()))

        item.SystemUpdate false
        r.EventFiringEnabled &lt;- true

    // member private CreateFolderPath : list:SPDocumentLibrary -&gt; path:string -&gt; SPFolder
    member private r.CreateFolderPath list path : SPFolder =
        r.CreateFolderPathRecursive list.RootFolder (path.Split [|'/'|] |&gt; Array.toList)

    // member private CreateFolderPathRecursive : folder:SPFolder -&gt; pathComponents:string list -&gt; SPFolder
    member private r.CreateFolderPathRecursive folder pathComponents =                
        match pathComponents with
        | [] -&gt; folder
        | head :: tail -&gt; 
            try
                let existingFolder = folder.SubFolders.[head]
                r.CreateFolderPathRecursive existingFolder tail
            with
                :? ArgumentException -&gt;
                    let newFolder = folder.SubFolders.Add head
                    r.CreateFolderPathRecursive newFolder tail

    // member private SetCustomVersionLabel : item:SPListItem -&gt; unit
    member private r.SetCustomVersionLabel item =
        r.EventFiringEnabled &lt;- false
        item.[r.CustomVersion] &lt;- r.GetOfficialVersionLabel item
        item.SystemUpdate false
        r.EventFiringEnabled &lt;- true  

    // member private GetCustomVersionLabel : item:SPListItem -&gt; string
    member private r.GetCustomVersionLabel item =
        item.[r.CustomVersion] :?&gt; string

    // member private GetOfficialVersionLabel : item:SPListItem -&gt; string
    member private r.GetOfficialVersionLabel item =
        item.Versions.[0].VersionLabel</pre>
<p>A couple of things to note about the F# implementation: first, it hardly specifies any types. They’re inferred by the compiler. Where type names do appear, it’s mainly because they’re required to unbox elements of an IEnumerable collection. Secondly, F# has <a href="http://stackoverflow.com/questions/5355334/what-are-the-benefits-of-such-flexible-self-identifiers-in-f">flexible self identifiers</a>. Methods must explicitly specify the name of the this reference in C# and use it when accessing members. Thirdly, arguments to general .NET methods are passed as a tuple value, i.e., as comma-delimited arguments surrounded by parenthesis.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2011/11/21/f-sharepoint-a-list-attachment-versioning-event-receiver/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding event receivers to SharePoint lists on the fly</title>
		<link>http://www.bugfree.dk/blog/2011/11/19/adding-event-receivers-to-sharepoint-lists-on-the-fly/</link>
		<comments>http://www.bugfree.dk/blog/2011/11/19/adding-event-receivers-to-sharepoint-lists-on-the-fly/#comments</comments>
		<pubDate>Sat, 19 Nov 2011 21:53:00 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1073</guid>
		<description><![CDATA[In versioning attachments in a SharePoint list using snapshotting, an event receiver was responsible for the heavy lifting. To enable versioning of a list, I could therefore have associated the receiver with a list by adding the usual registration XML to a feature. But versioning is a truly reusable building block that shouldn’t be restricted [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://www.bugfree.dk/blog/2011/11/17/versioning-attachments-in-a-sharepoint-list-using-snapshotting/">versioning attachments in a SharePoint list using snapshotting</a>, an event receiver was responsible for the heavy lifting. To enable versioning of a list, I could therefore have associated the receiver with a list by adding the usual registration XML to a feature. But versioning is a truly reusable building block that shouldn’t be restricted to lists that are known when the feature is created. A better solution would be to extend the SharePoint list settings page for all lists on a site on which the versioning feature is enabled. The user may then activate or deactivate attachment versioning on the fly.</p>
<p>This would involve adding or removing event receivers from a list as the user enables or disables versioning. The following extension method is one way to accomplish the addition-part in a type-safe manner:</p>
<pre class="prettyprint lang-cs">// definition 
public static class SPListExtensions {
    public static void RegisterEventReceiver&lt;TReceiver&gt;(this SPList list, 
            SPEventReceiverType receiverType, 
            int sequenceNumber) where TReceiver : SPItemEventReceiver {
        var assemblyName = typeof(TReceiver).Assembly.FullName;
        var className = typeof(TReceiver).FullName;

        (from SPEventReceiverDefinition definition in list.EventReceivers
         where definition.Assembly == assemblyName &amp;&amp;
               definition.Class == className &amp;&amp;
               definition.Type == receiverType
         select list.EventReceivers[definition.Id])
        .ToList()
        .ForEach(receiverToDelete =&gt; receiverToDelete.Delete());

        var receiver = list.EventReceivers.Add();
        receiver.Type = receiverType;
        receiver.Assembly = assemblyName;
        receiver.Class = className;
        receiver.SequenceNumber = sequenceNumber;
        receiver.Update();
        list.Update();
    }
}

// use
list.RegisterEventReceiver&lt;ListAttachmentVersioningEventReceiver&gt;(
    SPEventReceiverType.ItemAdded, 10000);
list.RegisterEventReceiver&lt;ListAttachmentVersioningEventReceiver&gt;(
    SPEventReceiverType.ItemUpdated, 10001);</pre>
<p>Under rare circumstances the (assembly, class, type) tuple may not be unique, i.e., the same receiver may be registered multiple times, albeit with different sequence numbers. In practice I never found any use for this functionality, though, which is why I didn’t include the sequence number in the where clause above, causing all registrations matching the tuple to be removed.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2011/11/19/adding-event-receivers-to-sharepoint-lists-on-the-fly/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Versioning attachments in a SharePoint list using snapshotting</title>
		<link>http://www.bugfree.dk/blog/2011/11/17/versioning-attachments-in-a-sharepoint-list-using-snapshotting/</link>
		<comments>http://www.bugfree.dk/blog/2011/11/17/versioning-attachments-in-a-sharepoint-list-using-snapshotting/#comments</comments>
		<pubDate>Thu, 17 Nov 2011 09:38:16 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1070</guid>
		<description><![CDATA[(See also the F# implementation and adding event receivers to a list on the fly.) Both SharePoint 2007 and 2010 support versioning for list items but not their attachments. No matter which version of a list item I look at, its attachments will always be the most recent. The attachment support seems to have been [...]]]></description>
			<content:encoded><![CDATA[<p>(See also the <a href="http://www.bugfree.dk/blog/2011/11/21/f-sharepoint-a-list-attachment-versioning-event-receiver/">F# implementation</a> and <a href="http://www.bugfree.dk/blog/2011/11/19/adding-event-receivers-to-sharepoint-lists-on-the-fly/">adding event receivers to a list on the fly</a>.)</p>
<p>Both SharePoint 2007 and 2010 support versioning for list items but not their attachments. No matter which version of a list item I look at, its attachments will always be the most recent. The attachment support seems to have been bolded on as an afterthought, resulting in behavior that’s counter-intuitive for developers as well as end-users. With SharePoint 2007 (and 2010), Microsoft <a href="http://support.microsoft.com/kb/943136">suggests</a> using a document library for proper attachment versioning. But I can’t substitute one with the other, since a list item may hold any number of attachments and an item in a document library may hold just one.</p>
<h4>Existing solution</h4>
<p>I counted on someone else having experienced a similar pain and come up with a workable cure. But except for <a href="http://codeshape.wordpress.com/2010/10/21/versioning-attachments-in-a-sharepoint-list-an-implementation/">Tim Ebenezer</a> the search come up empty. Tim on the other hand has done a great job of seamlessly integrating his attachment versioning feature into SharePoint. When I activate the feature on a site, it adds a versioning menu item to the list settings page for every list on the site. Unfortunately the core versioning logic, storing attachments in a shadow library using an event receiver, isn’t particularly robust. Among other use cases, it doesn’t properly deal with a user first deleting an attachment and then, some versions later, adding an attachment with the same name.</p>
<p>I therefore set out to implement my own solution based on Tim’s ideas, hooking into the synchronous ItemAdding, ItemUpdating, ItemAttachmentAdding, and ItemAttachmentDeleting events and maintaining a shadow library of versions. This approach, however, quickly turned into a painful one. When the synchronous events run, nothing has yet been written to the database – at this stage a new item doesn’t even have its Id set, and merely determining the number of attachments added and how far I’ve come with the processing is tricky.</p>
<p>The next challenge I encountered was that event handlers cannot easily share state across multiple calls because SharePoint creates a new instance of the receiver class for every event handled. Processing multiple attachments require a counter into the array of attachments to keep track of which ones I’d copied to the shadow list. I’d have to resort to some outside-object storage, keeping in mind that the receiver might execute concurrently. But which storage should I use? Session state may have been disabled, and polluting one of the property bags stored in the content database is messy and also not thread-safe.</p>
<p>Overall, with the synchronous approach too much work has to go into tracking the state of the versioning process.</p>
<h4>New solution</h4>
<p>A synchronous solution is very hard to get right because it’s forced to work at the level of individual attachments. SharePoint doesn’t have a synchronous event that fires after all attachments have been processed. After all, why provide such an event when everything has already happened? Thinking instead in terms of the asynchronous events of ItemUpdated and ItemAdded, I have exactly what’s needed to snapshot all attachments in one batch, making versioning a lot simpler. When these events fire the item and its attachments have already been written to the database and I can focus on how to generate the snapshots &#8212; copying attachments back and forth between lists &#8212; and not worry about what the user actual did to the attachments from one version to the next.</p>
<pre class="prettyprint lang-cs">// Prerequisites:
// 1. Create a Document Library named ShadowLibrary on the same site as the list to version
// 2. Add a row named CustomVersion of type string to the list to version
public class ListAttachmentVersioningEventReceiver : SPItemEventReceiver {
    private const string CustomVersion = &quot;CustomVersion&quot;;
    private const string ShadowLibrary = &quot;ShadowLibrary&quot;;

    public override void ItemAdded(SPItemEventProperties properties) {
        base.ItemUpdated(properties);
        SetCustomVersionLabel(properties.ListItem);
        CreateSnapshot(properties);
    }

    public override void ItemUpdated(SPItemEventProperties properties) {
        base.ItemUpdated(properties);

        var item = properties.ListItem;
        if (RollbackHappened(item)) {
            RestoreSnapshot(properties);
            SetCustomVersionLabel(item);
            CreateSnapshot(properties);
        }
        else {
            CreateSnapshot(properties);
            SetCustomVersionLabel(item);
        }
    }

    private void CreateSnapshot(SPItemEventProperties properties) {
        using (var site = properties.OpenWeb()) {
            var item = properties.ListItem;
            var shadowLibrary = site.Lists[ShadowLibrary] as SPDocumentLibrary;
            var path = string.Format(&quot;Versions/{0}/{1}&quot;, item.ID, GetOfficialVersionLabel(item));
            var shadowFolder = CreateFolderPath(shadowLibrary, path);

            foreach (string fileName in item.Attachments) {
                SPFile existingFile = item.ParentList.ParentWeb.GetFile(item.Attachments.UrlPrefix + fileName);
                SPFile newFile = shadowFolder.Files.Add(fileName, existingFile.OpenBinaryStream());
                newFile.Item.Update();                    
            }
        }
    }

    private bool RollbackHappened(SPListItem item) {
        var culture = CultureInfo.InvariantCulture;
        var currentVersion = float.Parse(GetOfficialVersionLabel(item), culture);
        var lastVersion = float.Parse(GetCustomVersionLabel(item), culture);
        return currentVersion &gt; lastVersion + 1;
    }

    private void RestoreSnapshot(SPItemEventProperties properties) {
        var item = properties.ListItem;
        var restoreVersion = GetCustomVersionLabel(item);
        EventFiringEnabled = false;

        item.Attachments.Cast&lt;string&gt;().ToList().ForEach(attachment =&gt; item.Attachments.Delete(attachment));
        using (var site = properties.OpenWeb()) {
            var path = string.Format(&quot;Versions/{0}/{1}&quot;, item.ID, restoreVersion);
            var shadowLibrary = site.Lists[ShadowLibrary] as SPDocumentLibrary;
            var source = CreateFolderPath(shadowLibrary, path);

            foreach (SPFile file in source.Files)
                item.Attachments.Add(file.Name, file.OpenBinary());
        }

        item.SystemUpdate(false);
        EventFiringEnabled = true;
    }

    // can only get folder creation to work with Document Libraries
    private SPFolder CreateFolderPath(SPDocumentLibrary list, string path) {
        return CreateFolderPathRecursive(list.RootFolder, path.Split('/').ToList());
    }

    private SPFolder CreateFolderPathRecursive(SPFolder folder, IList&lt;string&gt; pathComponents) {
        if (pathComponents.Count == 0)
            return folder;

        SPFolder newFolder;
        try {
            newFolder = folder.SubFolders[pathComponents.First()];
        }
        catch (ArgumentException) {
            newFolder = folder.SubFolders.Add(pathComponents.First());
        }

        pathComponents.RemoveAt(0);
        return CreateFolderPathRecursive(newFolder, pathComponents);
    }

    private void SetCustomVersionLabel(SPListItem item) {
        EventFiringEnabled = false;
        item[CustomVersion] = GetOfficialVersionLabel(item);
        item.SystemUpdate(false);
        EventFiringEnabled = true;
    }

    private string GetCustomVersionLabel(SPItem item) { return item[CustomVersion] as string; }
    private string GetOfficialVersionLabel(SPListItem item) { return item.Versions[0].VersionLabel; }
}</pre>
<p>When a list item is saved, I take a snapshot of the attachments, storing them in a folder structure like {Id}/{VersionNumber}/{Attachments} in the shadow document library. When a list item is restored to a previous version, existing attachments are first deleted before the ones from the snapshot are added back in, creating a new version of the list item.</p>
<p>Restoring previous versions also has a counter-intuitive meaning in SharePoint. Suppose in one version of a list item, I store a key in the item’s property bag, then I’d expect the property bag values to be specific to this version. But behind the scenes restore seems to work by cloning the current version and then copying only the values of the fields from the restore version to the new one. In other words, I can’t use the item’s property bag to store version specific information, such as a version tag to detect when a restore has occurred. I also can&#8217;t use the Modified field because SharePoint sets it to the time of the restore. To carry over version information I have to create and maintain a field of my own. Hence the CustomVersion field on the list to version.</p>
<p>Remember that because the ItemUpdated and ItemAdded execute asynchronously, all the snapshotting logic executes on a background thread, after control has returned to the user. Should an error occur at this point, the user will never see it and the snapshot may be left in an incomplete state. On the other hand, this approach scales well and doesn’t have to be fast because no user is awaiting the result.</p>
<p>Lastly, there’s one place in SharePoint where the versioning abstraction leaks through. It’s in the list item version dialog which displays older versions and enables restore to any previous version. The dialog will always show the most recent attachments.</p>
<h4>Improvements</h4>
<p>I could use the <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfile.etag.aspx">ETag</a> property of an SPFile object to implement a more efficient differential snapshotting algorithm that would conserve storage space. Compressing attachments before storing them in the shadow library might also be an option, although then I’d have to promote the ETag value to a shadow library field before compressing.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2011/11/17/versioning-attachments-in-a-sharepoint-list-using-snapshotting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Handy SharePoint 2010 extension methods for list definitions</title>
		<link>http://www.bugfree.dk/blog/2011/11/15/handy-sharepoint-2010-extension-methods-for-list-definitions/</link>
		<comments>http://www.bugfree.dk/blog/2011/11/15/handy-sharepoint-2010-extension-methods-for-list-definitions/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 05:59:18 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1068</guid>
		<description><![CDATA[A quick word on organizing extension methods: I usually collect them in an Extensions folder, appending Extensions to the name of class being extended and keeping with the one class per file convention. For brevity I’ve left out the using and the namespace part below. SPListCollection extensions In SharePoint 2010 the TryGetList method has been [...]]]></description>
			<content:encoded><![CDATA[<p>A quick word on organizing extension methods: I usually collect them in an Extensions folder, appending Extensions to the name of class being extended and keeping with the one class per file convention. For brevity I’ve left out the using and the namespace part below.</p>
<h4>SPListCollection extensions</h4>
<p>In SharePoint 2010 the <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splistcollection.trygetlist.aspx">TryGetList</a> method has been added to the <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splistcollection.aspx">SPListCollection</a> class. The method returns either an <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splist.aspx">SPList</a> instance matching the display name or null. Oftentimes, however, you want to do a lookup based on the internal name. Here’s an extension method that adheres to the semantics of TryGetList, but using the internal name. It relies on the fact that the RootFolder property of a list is actually its internal name:</p>
<pre class="prettyprint lang-cs">// definition
public static class SPListCollectionExtensions {
    public static SPList TryGetListByInternalName(this SPListCollection lists, string internalName) {
        return (from SPList l in lists
            where l.RootFolder.Name == internalName
            select l).SingleOrDefault();
    }
}

// use
if (site.Lists.TryGetListByInternalName(internalListName) == null)
   // list not found</pre>
<h4>SPFieldCollection extensions</h4>
<p>Using the <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfieldcollection.createnewfield.aspx">CreateNewField</a> method of the <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfieldcollection.aspx">SPFieldCollection</a> you can add new fields to a list. The particular annoying aspect of this method, however, is that when you want to continue working with its result, oftentimes you have to cast it to one of the <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfield.aspx">SPField</a> subclasses. But since the <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfieldtype.aspx">SPFieldType</a>, provided as one of the arguments to CreateNewField, closely relates to the actual SPField return type, an extension method is able to do the casting. This’ll expose mismatches at compile time instead of at runtime.</p>
<p>All it takes is for us to map out the relation between SPField and SPFieldType:</p>
<pre class="prettyprint lang-cs">// definition    
public static class SPFieldCollectionExtensions {
    public static TSPField CreateField&lt;TSPField&gt;(this SPFieldCollection fields, 
            string internalName, string displayName) where TSPField : SPField {
        var spFieldToFieldType = new Dictionary&lt;Type, SPFieldType&gt; {
            { typeof(SPFieldDateTime), SPFieldType.DateTime },
            { typeof(SPFieldNumber), SPFieldType.Number },
            { typeof(SPFieldUser), SPFieldType.User },
            { typeof(SPFieldBoolean), SPFieldType.Boolean },
            { typeof(SPFieldMultiLineText), SPFieldType.Note },
            { typeof(SPFieldText), SPFieldType.Text }
        };

        var fieldType = spFieldToFieldType[typeof(TSPField)]; 
        var list = fields.List;
        var field = list.Fields[list.Fields.Add(internalName, fieldType, false)];
        field.Title = displayName;
        field.Update();
        return field as TSPField;
    }
}

// use
l.Fields.CreateField&lt;SPFieldBoolean&gt;(internalName, &quot;displayName&quot;);</pre>
<p>Taking the CreateField extension method one step further, oftentimes you want to set properties besides internal name and display name. For that purpose I’ve defined a CreateField method that accepts an Action&lt;TField&gt;. This allows you to reuse common property settings across fields for brevity and consistency while at the same time maintaining strong typing.</p>
<pre class="prettyprint lang-cs">// definition
public static TSPField CreateField&lt;TSPField&gt;(this SPFieldCollection fields, 
        string internalName, string displayName, 
        Action&lt;TSPField&gt; setAdditionalProperties) where TSPField : SPField {
    var newField = CreateField&lt;TSPField&gt;(fields, internalName, displayName);
    setAdditionalProperties(newField);
    newField.Update();
    return newField;
}

// use
public static Action&lt;SPFieldMultiLineText&gt; RichTextProperties = f =&gt; {
    f.RichText = true;
    f.RichTextMode = SPRichTextMode.FullHtml;
};

l.Fields.CreateField&lt;SPFieldBoolean&gt;(internalName, &quot;displayName&quot;, f =&gt; f.Required = true);
l.Fields.CreateField(internalName, &quot;displayName&quot;, RichTextProperties);</pre>
<p>With the Comment field, you can leave out the type argument because the compiler infers it based on the type of the Action delegate.</p>
<p>Similar to CreateField, I’ve defined two additional extension methods for creating lookup fields:</p>
<pre class="prettyprint lang-cs">// definition
public static TSPField CreateLookup&lt;TSPField&gt;(this SPFieldCollection fields, 
        string lookupListName, string internalName, 
        string displayName) where TSPField : SPFieldLookup {
    var currentList = fields.List;
    var lookupList = currentList.ParentWeb.Lists.TryGetListByInternalName(lookupListName);
    var newField = currentList.Fields[currentList.Fields.AddLookup(internalName, lookupList.ID, false)];
    newField.Title = displayName;
    newField.Update();
    return newField as TSPField;
}

public static TSPField CreateLookup&lt;TSPField&gt;(this SPFieldCollection fields, 
        string lookupListName, string internalName, string displayName, 
        Action&lt;TSPField&gt; setAdditionalProperties) where TSPField : SPFieldLookup {
    var newField = CreateLookup&lt;TSPField&gt;(fields, lookupListName, internalName, displayName);
    setAdditionalProperties(newField);
    newField.Update();
    return newField;
}

// use
l.Fields.CreateLookup&lt;SPFieldLookup&gt;(lookupListName, internalName, displayName, f =&gt; f.AllowMultipleValues = true);</pre>
<p>These extension methods makes using the SharePoint API more type-safe and concise, and defining lists using these methods and the <a href="http://www.bugfree.dk/blog/2010/01/11/sharepoint-list-definition-using-the-template-pattern/">template approach</a> saves me from writing a lot of repetitive code.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2011/11/15/handy-sharepoint-2010-extension-methods-for-list-definitions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A table-driven approach to creating SharePoint sites with PowerShell</title>
		<link>http://www.bugfree.dk/blog/2011/11/13/a-table-driven-approach-to-creating-sharepoint-sites-with-powershell/</link>
		<comments>http://www.bugfree.dk/blog/2011/11/13/a-table-driven-approach-to-creating-sharepoint-sites-with-powershell/#comments</comments>
		<pubDate>Sun, 13 Nov 2011 15:31:29 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Powershell]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1069</guid>
		<description><![CDATA[While cleaning up some PowerShell installations scripts that I wrote some time ago, I come across the following piece of code (modified slightly for anonymity) for creating a hierarchy of SharePoint sites and setting the locale for a subset of the sites. It works but it sure doesn’t adhere to the DRY principle. New-SPWeb -url [...]]]></description>
			<content:encoded><![CDATA[<p>While cleaning up some PowerShell installations scripts that I wrote some time ago, I come across the following piece of code (modified slightly for anonymity) for creating a hierarchy of SharePoint sites and setting the locale for a subset of the sites. It works but it sure doesn’t adhere to the DRY principle.</p>
<pre class="prettyprint">New-SPWeb -url $base_url -addtoquicklaunch -template "STS#1" -name "Base"
New-SPWeb -url $base_url/Dk -addtoquicklaunch -template "STS#1" -name "Dk"
New-SPWeb -url $base_url/Uk -addtoquicklaunch -template "STS#1" -name "Uk"
New-SPWeb -url $base_url/Dk/BusinessUnit1 -addtoquicklaunch -template "STS#1" -name "BusinessUnit1"  
New-SPWeb -url $base_url/Dk/BusinessUnit2 -addtoquicklaunch -template "STS#1" -name "BusinessUnit2"
New-SPWeb -url $base_url/Uk/BusinessUnit1 -addtoquicklaunch -template "STS#1" -name "BusinessUnit1"
New-SPWeb -url $base_url/Uk/BusinessUnit2 -addtoquicklaunch -template "STS#1" -name "BusinessUnit2"

$dk = Get-SPWeb $base_url/Dk
$dkBusinessUnit1 = Get-SPWeb $base_url/Dk/BusinessUnit1
$dkBusinessUnit2 = Get-SPWeb $base_url/Dk/BusinessUnit2

$locale = [System.Globalization.CultureInfo]::CreateSpecificCulture("da-DK")
$dk.Locale = $locale
$dk.Update()

$dkBusinessUnit1.Locale = $locale
$dkBusinessUnit1.Update()
  
$dkBusinessUnit2.Locale = $locale
$dkBusinessUnit2.Update()</pre>
<p>How can we reduce this repetition? Well, it repeats because we’ve made the common mistake of mixing logic with data. One way to separate the two is using a table-driven approach, i.e., extract the varying parts, the data, into a table and rewrite the logic so it’s parameterized by the table. After some trial and error with PowerShell here’s the code I ended up with:</p>
<pre class="prettyprint">$sites = @( @("", "Base"), 
            @("Dk", "Dk", "da-DK"),
            @("Uk", "Uk"),
            @("Dk/BusinessUnit1", "BusinessUnit1", "da-DK"),
            @("Dk/BusinessUnit2", "BusinessUnit2", "da-DK"),
            @("Uk/BusinessUnit1", "BusinessUnit1"),
            @("Uk/BusinessUnit2", "BusinessUnit2") )

$sites | foreach {
  $url, $title, $culture = $_
  $newSite = New-SPWeb -url "$base_url/$url" -addtoquicklaunch -template "STS#1" -name $title
    
  if ($culture -ne "") {
    $locale = [System.Globalization.CultureInfo]::CreateSpecificCulture($culture)
    $newSite.Locale = $locale
    $newSite.Update()
  }
}</pre>
<p>So far so good. The un-installation part of the script, however, follows the same pattern of repetition:</p>
<pre class="prettyprint">Remove-SPWeb -identity $base_url/Uk/BusinessUnit2 -confirm:$false -ErrorAction SilentlyContinue
Remove-SPWeb -identity $base_url/Uk/BusinessUnit1 -confirm:$false -ErrorAction SilentlyContinue
Remove-SPWeb -identity $base_url/Dk/BusinessUnit2 -confirm:$false -ErrorAction SilentlyContinue
Remove-SPWeb -identity $base_url/Dk/BusinessUnit1 -confirm:$false -ErrorAction SilentlyContinue
Remove-SPWeb -identity $base_url/Dk -confirm:$false -ErrorAction SilentlyContinue
Remove-SPWeb -identity $base_url/Uk -confirm:$false -ErrorAction SilentlyContinue
Remove-SPWeb -identity $base_url -confirm:$false</pre>
<p>But now that we have the table of sites at hand, we can easily make the site removal table-driven as well:</p>
<pre class="prettyprint">function Reverse($array) {
  $clone = $array.Clone()
  [Array]::Reverse($clone)
  $clone
}

Reverse($sites) | foreach {
  $url = $_[0]  
  Remove-SPWeb -identity "$base_url/$url" -confirm:$false -ErrorAction SilentlyContinue
}</pre>
<p>I’m sure the code could be written more elegantly, but given my working knowledge of PowerShell I’m satisfied with the result. I especially like the functional programming style.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2011/11/13/a-table-driven-approach-to-creating-sharepoint-sites-with-powershell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Notes from Geek Night talk on Advanced Windsor Tricks</title>
		<link>http://www.bugfree.dk/blog/2010/12/19/notes-from-geek-night-talk-on-advanced-windsor-tricks/</link>
		<comments>http://www.bugfree.dk/blog/2010/12/19/notes-from-geek-night-talk-on-advanced-windsor-tricks/#comments</comments>
		<pubDate>Sun, 19 Dec 2010 11:03:00 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Tool]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1066</guid>
		<description><![CDATA[My notes from a talk on Windsor by Mogens Heller Grabe which I attended this week. Slides and code are available through Dropbox, but I don’t know for how long. Use an Inversion of Control container (IoC) like Windsor to create an architecture that responds well to change, i.e., an architecture that promotes looser coupling [...]]]></description>
			<content:encoded><![CDATA[<p>My notes from a <a href="http://secure.trifork.com/aarhus-2010/freeevent/index.jsp?eventOID=2756">talk on Windsor</a> by <a href="http://mookid.dk/oncode">Mogens Heller Grabe</a> which I attended this week. <a href="http://dl.dropbox.com/u/8614955/Avancerede%20Windsor-tricks%20-%20H%C3%B8je%20Taastrup.pdf">Slides</a> and <a href="http://dl.dropbox.com/u/8614955/Avancerede%20Windsor-tricks.zip">code</a> are available through Dropbox, but I don’t know for how long.</p>
<ul>
<li>Use an Inversion of Control container (IoC) like <a href="http://stw.castleproject.org/Windsor.MainPage.ashx">Windsor</a> to create an architecture that responds well to change, i.e., an architecture that promotes looser coupling and higher cohesion </li>
<li>The ability to write unit tests against a code base is a good measure of its degree of coupling </li>
<li>By having components depend on interfaces, you’re free to switch the implementation at runtime, introducing flexibility into the software </li>
<li>Avoid having concrete components talk to each other. It makes it hard for the two to vary independently, e.g., adding logging later can only be done by tearing components apart and putting them back together </li>
<li>At runtime the IoC container recursively composes these smaller components into an object graph, e.g., by passing concrete implementations through the constructors to satisfy the dependencies </li>
<li>One alternative to using an IoC container is using a service locator. Each component’s constructor would then ask the locator for its dependent components. While this approach works, it makes testing components in isolation difficult because all dependencies are now locked away inside the service locator. Instead, by having all dependencies supplied in the constructor, unit tests can directly supply fakes implementations </li>
<li>When software is only used in one environment it tends to be fairly inflexible because it’s only suited for that one purpose. As soon as you design it to be used in two or more environments it becomes more flexible. Thing of different environments as unit test, staging, production, and so on </li>
<li>The idea is for components to not have to be modified depending on the where they’re running. It’s the IoC container that dynamically tie components together based on the environment </li>
<li>Suppose you didn’t use a IoC container. Then ultimately the top-level object would have to pass concrete instances down the chain. The top-level object may well be the UI layer. But having the UI layer know about data access components, service components, and logging components isn’t ideal. Instead use an IoC container, which is nothing more than a factory for components </li>
<li>With the Windsor IoC container (and most others), the usage pattern typically involves three stages
<ul>
<li>Register: tie together interfaces with concrete implementations </li>
<li>Resolve: return concrete implementations of interfaces required to satisfy the dependencies of an object </li>
<li>Release: dispose of concrete implementations </li>
</ul>
</li>
<li>Most people only use a fraction of the functionality of an IoC container. Instead of taking dependency of a full-blown container, you could easily <a href="http://msdn.microsoft.com/en-us/magazine/cc337885.aspx">roll your own IoC container</a> that implements the core functionality in a few dozen lines of code &#8212; in an associated <a href="http://www.dotnetrocks.com/default.aspx?showNum=362">.NET Rocks</a> and <a href="http://www.dnrtv.com/default.aspx?showNum=126">DnrTV</a> episode <a href="http://www.jameskovacs.com">James Kovacs</a> elaborates on his original article </li>
<li>The goal of using a container isn’t to get rid of calls to the new operator. It’s to not use the new operator for the parts of an applications where flexibility is required </li>
<li>Simple forms of <a href="http://en.wikipedia.org/wiki/Aspect_oriented_programming">Aspect Oriented Programming</a> are possible using interceptors </li>
<li>Windsor supports the decorator pattern so you can have one component wrap another at runtime. This lets you implement features such as logging without actually modifying the original component. It’s an example of adhering to the <a href="http://en.wikipedia.org/wiki/Open/closed_principle">open/close principle</a> by which classes should be open for extension, but closed for modification. In other words: don’t edit the original source code to introduce new behavior. Instead use methods of composition </li>
<li>Avoid configuring Windsor through XML and instead use the fluent interface &#8212; perhaps in a separate assembly so only it needs to be redeployed when the configuration changes. When a value, such as a connection string needs to be configurable, create a section in app.config and add the value there. Windsor will know how to locate the value when instantiating objects</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2010/12/19/notes-from-geek-night-talk-on-advanced-windsor-tricks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Notes from Geek Night talk on SOA Done Right Using NServiceBus</title>
		<link>http://www.bugfree.dk/blog/2010/12/11/notes-from-geek-night-talk-on-soa-done-right-using-nservicebus/</link>
		<comments>http://www.bugfree.dk/blog/2010/12/11/notes-from-geek-night-talk-on-soa-done-right-using-nservicebus/#comments</comments>
		<pubDate>Sat, 11 Dec 2010 08:39:00 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Tool]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1065</guid>
		<description><![CDATA[My notes from a talk on NServiceBus by Mogens Heller Grabe which I attended this week. Slides and code are available through Dropbox, but I don’t know for how long. Enterprise service bus An architectural pattern rather than a specific technology or product The ethernet of SOA Types of service bus Centralized: a broker more [...]]]></description>
			<content:encoded><![CDATA[<p>My notes from a <a href="https://secure.trifork.com/aarhus-2010/freeevent/index.jsp?eventOID=2758">talk on NServiceBus</a> by <a href="http://mookid.dk/oncode">Mogens Heller Grabe</a> which I attended this week. <a href="http://dl.dropbox.com/u/8614955/SOA%20Done%20Right%21%20-%20H%C3%B8je%20Taastrup.pdf">Slides</a> and <a href="http://dl.dropbox.com/u/8614955/SOA%20Done%20Right%21.zip">code</a> are available through Dropbox, but I don’t know for how long.</p>
<ul>
<li>Enterprise service bus
<ul>
<li>An architectural pattern rather than a specific technology or product </li>
<li>The ethernet of SOA </li>
</ul>
</li>
<li>Types of service bus
<ul>
<li>Centralized: a broker more than a bus, e.g., BizTalk </li>
<li>Decentralized: a real service bus, e.g., <a href="http://www.nservicebus.com">NServiceBus</a>, <a href="http://code.google.com/p/masstransit">Mass Transit</a>, <a href="http://ayende.com/Blog/archive/2008/12/17/rhino-service-bus.aspx">Rhino Service Bus</a>, <a href="http://msdn.microsoft.com/en-us/magazine/dd569756.aspx">MS .NET Service bus</a> </li>
</ul>
</li>
<li>The current version 2.0 of NServiceBus is free whereas the binary version 2.5 will contain limitations. The limitations can be disabled by downloading and compiling the source code yourself </li>
<li>NServiceBus is designed to address the <a href="http://en.wikipedia.org/wiki/Fallacies_of_Distributed_Computing">fallacies of distributed computing</a>
<ul>
<li>It primarily addresses the fallacies through the use of reliable one-way messaging </li>
<li>Reliable means messages are stored in a queue, such a MSMQ, which is part of all recent Windows installations. The assumption being that the queue is always present and ready to receive messages </li>
<li>One-way means messages are asynchronous and fire-and-forget. The destination service doesn’t have to be online when a message goes into its queue, which makes services temporally independent. At some point in the future the service may post a reply to the client’s queue </li>
<li>Messaging means that any action is accomplished by posting a self-contained message, containing the type of operation and its parameters, to the queue of a service </li>
<li>With NServiceBus, a class is marked with an interface to describe that it’s a type of message. Instances of the class are then serialized using a standard XML or binary serializer and stored in a queue </li>
</ul>
</li>
<li>NServiceBus service != traditional web service
<ul>
<li>An NServiceBus service is a class that implements an interface </li>
<li>Using a message queue is more reliable when the service has to make calls to other services as part of its operation. With a traditional web service, calling other services from within makes the service slower and less reliable. If only one dependent service is down it’s like with old Christmas lights wired in series: the entire stack may be down. Queues on the other hand introduce a save place, a <a href="http://elegantcode.com/2010/12/17/christmas-light-architectures-are-not-that-shiny">stabilization point</a>, to temporarily store messages </li>
<li>A service is typically configured with an input queue that identifies it to others and an error queue that messages are routed to after some number of retries. In addition, each service may be configured with a number of threads to use to parallelize message processing </li>
</ul>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2010/12/11/notes-from-geek-night-talk-on-soa-done-right-using-nservicebus/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Notes from Tech Talk on Advanced .NET debugging with Windbg</title>
		<link>http://www.bugfree.dk/blog/2010/11/28/notes-from-tech-talk-on-advanced-net-debugging-with-windbg/</link>
		<comments>http://www.bugfree.dk/blog/2010/11/28/notes-from-tech-talk-on-advanced-net-debugging-with-windbg/#comments</comments>
		<pubDate>Sun, 28 Nov 2010 11:02:20 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Tool]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1064</guid>
		<description><![CDATA[My notes from a talk on Windbg by Brian Rasmussen which I attended this week. The talk was recorded and parts one and two are available though Channel 9. Windbg isn’t a replacement for VS, but VS doesn’t handle some advanced cases Windbg is a free user mode/kernel mode debugger which is part of the [...]]]></description>
			<content:encoded><![CDATA[<p>My notes from a <a href="http://kodehoved.dk/?p=696">talk on Windbg</a> by <a href="http://kodehoved.dk/?page_id=27">Brian Rasmussen</a> which I attended this week. The talk was recorded and parts <a href="http://channel9.msdn.com/posts/MDCC-TechTalk-Advanced-NET-Debugging-part-1">one</a> and <a href="http://channel9.msdn.com/posts/MDCC-TechTalk-Advanced-NET-Debugging-part-2">two</a> are available though Channel 9.</p>
<ul>
<li>Windbg isn’t a replacement for VS, but VS doesn’t handle some advanced cases </li>
<li>Windbg is a free user mode/kernel mode debugger which is part of the <a href="http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx">Debugger Tools for Windows</a> </li>
<li>Customers may not be happy installing VS to debug code in production since it installs a lot of components and requires restarts
<ul>
<li>Windbg requires only a simple installation once you extract the redistributable from the Debugger Tools for Windows <!--EndFragment--></li>
</ul>
</li>
<li>Loading <a href="http://msdn.microsoft.com/en-us/library/bb190764(v=VS.100).aspx">SOS.dll</a> from the Microsoft .NET folder into Windbg makes it understand .NET
<ul>
<li>With SOS.dll loaded, you can look into the CLR and its data structures </li>
<li>Make sure to load the right SOS.dll for your runtime </li>
<li>SOS.dll is also available for the Silverlight runtime </li>
</ul>
</li>
<li>Debugger Markup Language support is available for version 4 of SOS.dll
<ul>
<li>Provides hyperlinks in the command output of SOS </li>
</ul>
</li>
<li>Like with the VS debugger, you can insert Debug.Break() in your demo app and have Windbg halt on it
<ul>
<li>Release builds can be debugged with Windbg </li>
<li>Release builds also contain symbols. Like with debug builds, symbols are stored in a separate file </li>
<li>Release builds make debugging harder because the jitter kicks in and modifies the code </li>
<li>The 64 bit calling convention of passing arguments via registers makes it harder to locate information when debugging </li>
</ul>
</li>
<li>Windbg generally needs symbols loaded, although it’s less important when debugging managed code
<ul>
<li>Use MS’ public symbol server to load symbols on demand </li>
<li>Set the <a href="http://support.microsoft.com/kb/311503">_NT_SYMBOL_PATH</a> environment variable to point to your symbols (will affect VS as well) </li>
<li>Or use the <a href="http://msdn.microsoft.com/en-us/library/ff565400(VS.85).aspx">.symfix</a> command from within Windbg </li>
</ul>
</li>
<li>Popular extensions to Windbg: <a href="http://www.stevestechspot.com/SOSEXV40NowAvailable.aspx">SOSEX</a> and <a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=5c068e9f-ebfe-48a5-8b2f-0ad6ab454ad4&amp;displaylang=en">Psscor2</a> (replacement for SOS, useful for ASP.NET debugging) </li>
<li>Create dump file to analyze: use task manager or <a href="http://support.microsoft.com/kb/286350">ADPlus</a> or <a href="http://technet.microsoft.com/en-us/sysinternals/dd996900.aspx">ProcDump</a> from Sysinternals, which can dump based on triggers </li>
<li>ADPlus collects crash dumps or hang dumps
<ul>
<li>Hang dumps can be captured from the same process multiple times and may be useful when debugging deadlocks or resource leaks </li>
<li>When you capture a hang dump, the process is halted for the dump period and is then restarted </li>
</ul>
</li>
<li>A *32 process in task manager is actually a 64 bit process when you dump it
<ul>
<li><a href="http://en.wikipedia.org/wiki/WoW64">WoW64.dll</a> is involved when dumping from the task manager </li>
<li>Not what you typically want because you don’t get full access to 32 bit process information </li>
</ul>
</li>
<li>A .NET application is hosted within the CLR which is itself hosted within a regular Windows process
<ul>
<li>Looking at memory usage with the task manager therefore doesn’t tell you much about the .NET part </li>
</ul>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2010/11/28/notes-from-tech-talk-on-advanced-net-debugging-with-windbg/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Demystifying LINQ to Objects</title>
		<link>http://www.bugfree.dk/blog/2010/10/19/demystifying-linq-to-objects/</link>
		<comments>http://www.bugfree.dk/blog/2010/10/19/demystifying-linq-to-objects/#comments</comments>
		<pubDate>Tue, 19 Oct 2010 07:28:37 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[LINQ]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1062</guid>
		<description><![CDATA[To improve my understanding of LINQ, I’ve long wanted to learn how LINQ to Objects works under the covers. I&#8217;ll do so by relating query expression syntax to method invocation syntax and lambda expressions to generic delegates. Since many of the building blocks that make up LINQ are nothing more than syntactic sugar around .NET [...]]]></description>
			<content:encoded><![CDATA[<p>To improve my understanding of <a href="http://msdn.microsoft.com/en-us/netframework/aa904594.aspx">LINQ</a>, I’ve long wanted to learn how <a href="http://download.microsoft.com/download/5/8/6/5868081c-68aa-40de-9a45-a3803d8134b8/standard_query_operators.doc">LINQ to Objects</a> works under the covers. I&#8217;ll do so by relating query expression syntax to method invocation syntax and lambda expressions to generic delegates. Since many of the building blocks that make up LINQ are nothing more than <a href="http://en.wikipedia.org/wiki/Syntactic_sugar">syntactic sugar</a> around .NET 2.0 constructs, learning LINQ in terms of .NET 2.0 is one way to get into the more functional spirit of C#.</p>
<p>To set the stage, I’ve created an array of people to query.</p>
<pre class="prettyprint lang-cs">Person[] people = new[] { new Person { Age = 1, ...}, ... };</pre>
<p>It’s worth noting that all arrays implicitly derive from the <a href="http://msdn.microsoft.com/en-us/library/system.array.aspx">Array</a> class. It’s a special class that only the compiler and the runtime may derive from. Doing so yourself is rewarded with a compiler error stating simply that the class cannot be derived from. What’s also not apparent from the definition of the Array class is that, as of .NET 2.0, it also implements <a href="http://msdn.microsoft.com/en-us/library/5y536ey6.aspx">IList&lt;T&gt;</a>, <a href="http://msdn.microsoft.com/en-us/library/92t2ye13.aspx">ICollection&lt;T&gt;</a>, and <a href="http://msdn.microsoft.com/en-us/library/9eekhta0.aspx">IEnumerable&lt;T&gt;</a>, which derive from the corresponding non-generic interfaces.</p>
<pre class="prettyprint lang-cs">public abstract class Array :
    ICloneable, IList, ICollection,
    IEnumerable, IStructuralComparable, IStructuralEquatable</pre>
<p>The runtime takes special care of extending the Array type with implementations of the generic interfaces based on the type of object that the array stores. That’s why the interfaces are invisible in the documentation. Any array of type T &#8212; in this case Person &#8212; will therefore implement, among others, the IEnumerable&lt;T&gt; interface. It’s the implementation of this interface on a class that enables LINQ to Objects to query any array or collection.</p>
<h4>Query expression syntax</h4>
<p>Let&#8217;s create a simple query using query expression syntax. To support it, additional keywords have been added to C# to express common query operators. Examples of what’s not supported with query expression syntax are the <a href="http://msdn.microsoft.com/en-us/library/bb338442.aspx">Sum</a>, <a href="http://msdn.microsoft.com/en-us/library/bb503062.aspx">Take</a>, and <a href="http://msdn.microsoft.com/en-us/library/bb358985.aspx">Skip</a> query operators. In those cases you can combine query expression with method invocation syntax or write everything using the latter.</p>
<pre class="prettyprint lang-cs">var q = from p in people
        where p.Age &gt; 25
        select p;</pre>
<h4>Method invocation syntax</h4>
<p>To make matters transparent, let’s not rely on type inference and the var keyword for typing the result. At the same time, let&#8217;s assume the role of the compiler and translate the query expression syntax into method invocation syntax with lambda expressions. Each standard query operator, such as <a href="http://msdn.microsoft.com/en-us/library/bb534803.aspx">Where</a> and <a href="http://msdn.microsoft.com/en-us/library/bb548891.aspx">Select</a>, translates to a corresponding method invocation on the collection, oftentimes with a lambda expression as the argument. Both representations are semantically equivalent, but for this simple query method invocation syntax appears more complex. This is generally not the case for either representation as you can try out with a tool like <a href="http://www.bugfree.dk/blog/2008/06/29/prototyping-linq-using-linqpad">LINQPad</a>.</p>
<pre class="prettyprint lang-cs">IEnumerable&lt;Person&gt; r = people
    .Where(p =&gt; p.Age &gt; 25)
    .Select(p =&gt; p);</pre>
<p>The concise nature of the code is due to the compiler inferring the type arguments to Where and Select and the type of the lambda expression. In this case, because the collection stores objects of type Person, the type arguments of the generic methods as well as the type of the lambda expression is also of type Person. To make these types explicit, you can substitute real types for the generic ones in the definition of Where and Select provided later.</p>
<pre class="prettyprint lang-cs">IEnumerable&lt;Person&gt; s = people
    .Where&lt;Person&gt;((Person p) =&gt; p.Age &gt; 25)
    .Select&lt;Person, Person&gt;((Person p) =&gt; p);</pre>
<h4>Generic delegates</h4>
<p>With the type specifications made explicit, it’s more obvious how lambda expressions are compatible with delegates. A lambda expression is nothing more than a short-hand notation for a delegate, a type-safe pointer to a piece of code, to be passed into a method. Hence, a lambda expression can be substituted with an anonymous delegate by wrapping it in additional ceremony.</p>
<pre class="prettyprint lang-cs">IEnumerable&lt;Person&gt; t = people
    .Where&lt;Person&gt;(delegate(Person p) { return p.Age &gt; 25; })
    .Select&lt;Person, Person&gt;(delegate(Person p) { return p; });</pre>
<p>To make delegates type safe, their definition include the return type and the types of the arguments passed into it. This is unfortunate since the standard query operators must be able to work on any type of object. LINQ therefore relies on generic delegates in the definition of its operators. Like with other generic types, the compiler and runtime work together to generate real delegates based on the specified, or inferred, return type and types of arguments. Delegates like the ones below for Where and Select are what&#8217;s generated by the runtime.</p>
<pre class="prettyprint lang-cs">// delegate Boolean WhereDelegate(Person p);
// delegate Person SelectDelegate(Person p);
bool WhereClause(Person p) { return p.Age &gt; 25; }
Person SelectClause(Person p) { return p; }

IEnumerable&lt;Person&gt; u = people
    .Where&lt;Person&gt;(WhereClause)
    .Select&lt;Person, Person&gt;(SelectClause);</pre>
<p>LINQ relies on a set of generic delegates defined in the .NET framework. These delegates come in two flavors: those that return void, named Action, and those that don’t, named Func. You can use these delegates <a href="http://simpleprogrammer.com/2010/09/24/explaining-what-action-and-func-are">in your own code</a> to not only parameterize methods by value but by functionality.</p>
<pre class="prettyprint lang-cs">delegate void Action();
delegate void Action&lt;T&gt;(T obj);
delegate void Action&lt;T1, T2&gt;(T1 arg1, T2 arg2);
// up to eight arguments

delegate TResult Func&lt;TResult&gt;();
delegate TResult Func&lt;T, TResult&gt;(T arg);
delegate TResult Func&lt;T1, T2, TResult&gt;(T1 arg1, T2 arg2);
// up to eight arguments</pre>
<h4>Extension methods</h4>
<p>Each of the 50 or so standard query operators is defined on the <a href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.aspx">Enumerable</a> class with the this modifier on their first IEnumerable&lt;T&gt; argument. This makes them <a href="http://en.wikipedia.org/wiki/Extension_method">extension methods</a> to every object that implements IEnumerable&lt;T&gt;. From the definition of the Where operator below, it then follows that when you write &quot;Where(p =&gt; p.Age &gt; 25)&quot;, the compiler infers that because Where is called on a collection of type Person, p must also be of type Person. Furthermore, because the result of the comparison is a bool, the lambda expression is compatible with a delegate that accepts a type Person and returns a type bool. In other words, the matching Where has a signature like the commented one below.</p>
<p>The purpose of the Where operator is to filter a collection based on a predicate, the mathematical term for a function that returns true or false. The people that satisfy the predicate is therefore returned as an IEnumerable&lt;Person&gt;. However, the <a href="http://en.csharp-online.net/CSharp_Coding_Solutions%E2%80%94What_Does_Yield_Keyword_Generate">yield keyword</a> adds an interesting twist to the return of Where and Select and other operators that return IEnumerable&lt;T&gt;. Instead of the operator iterating the source collection and returning every element of the result at once, the yield keyword instructs the compiler to emit a state machine so the operator can keep track of how far through the source collection it is, and return one resulting element at a time. The effect is <a href="http://en.wikipedia.org/wiki/Lazy_evaluation">lazy evaluation</a> of LINQ to Objects queries.</p>
<p>In the example, the output of Where goes into Select whose output may goto the console using a foreach. To understand yield, think of the foreach that writes to the console as pulling on a string of objects connecting Select to Where to the source collection. Each iteration of the loop pulls the string just enough to get at the next resulting element. This may in turn require Where to iterate multiple times until the predicate is once again satisfied. </p>
<pre class="prettyprint lang-cs">// IEnumerable&lt;Person&gt; Where&lt;Person&gt;(
//     IEnumerable&lt;Person&gt; source,
//     Func&lt;Person, bool&gt; predicate)

public static IEnumerable&lt;TSource&gt; Where&lt;TSource&gt;(
    this IEnumerable&lt;TSource&gt; source,
    Func&lt;TSource, bool&gt; predicate) {
    foreach (TSource element in source) {
        if (predicate(element))
            yield return element;
    }
}</pre>
<p>The Select operator is an example of one whose input type may differ from its output type. By its very nature, it projects one type onto another. It can even project onto an anonomous type, like in &quot;Select(p =&gt; new { x = p.Name })&quot;, but then the var keyword must be used for its return type. In the example I project from Person to Person, which makes the matching signature of Select like the commented one below.</p>
<pre class="prettyprint lang-cs">// IEnumerable&lt;Person&gt; Select&lt;Person, Person&gt;(
//     this IEnumerable&lt;Person&gt; source,
//     Func&lt;Person, Person&gt; selector)

public static IEnumerable&lt;TResult&gt; Select&lt;TSource, TResult&gt;(
    this IEnumerable&lt;TSource&gt; source,
    Func&lt;TSource, TResult&gt; selector) {
    foreach (TSource element in source)
        yield return selector(element);
}</pre>
<p>The ability to chain methods together to form a data pipeline is what adds real power to LINQ. Although the idea of chaining methods together is old, the traditional approach of each method returning a new or mutated instance works best for objects of your own. Imagine adding to the IEnumerable&lt;T&gt; interface a set of query operators. Then every collection would have to provide implementations for Where, Select, and so on. Also, it wouldn’t be possible to add new operators in vNext of .NET without breaking existing code implementing the interface.</p>
<p>Extension methods solve this issue by providing the necessary syntactic sugar to make chaining of methods on a collection feel like chaining on an object of your own. Behind the scenes, the compiler rewrites calls to extension methods to static methods.</p>
<pre class="prettyprint lang-cs">var v = Enumerable.Select(
    Enumerable.Where(people, p =&gt; p.Age &gt; 25),
    p =&gt; p);</pre>
<p>Note how, without the use of extension methods, operations must be specified in the opposite order in which they’re executed. This doesn&#8217;t read as nicely as the “infix” syntax when many operations are chained together.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2010/10/19/demystifying-linq-to-objects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Essential requirements for a developer automation tool</title>
		<link>http://www.bugfree.dk/blog/2010/09/26/essential-requirements-for-a-developer-automation-tool/</link>
		<comments>http://www.bugfree.dk/blog/2010/09/26/essential-requirements-for-a-developer-automation-tool/#comments</comments>
		<pubDate>Sun, 26 Sep 2010 11:19:26 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Process]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Tool]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1058</guid>
		<description><![CDATA[Developer automation is a subject that I&#8217;ve always felt passionate about. Unit testing may be the most common example, but other tasks may include check-out of source code, build, deploy, setup, and warm-up of an application. I may even want one system rule them all and have the same automation drive continuous integration. Whatever the [...]]]></description>
			<content:encoded><![CDATA[<p>Developer automation is a subject that I&#8217;ve always felt passionate about. Unit testing may be the most common example, but other tasks may include check-out of source code, build, deploy, setup, and warm-up of an application. I may even want <a href="http://simpleprogrammer.com/2010/09/03/one-build-to-rule-them-all">one system rule them all</a> and have the same automation drive <a href="http://martinfowler.com/articles/continuousIntegration.html">continuous integration</a>. Whatever the use, to fully reap the benefits of automation, a developer should master at least one automation tool the same way he masters other developer tools. This and later posts capture my experiences with a few such automation tools centered around Windows and .NET, starting with why the ubiquitous <a href="http://en.wikipedia.org/wiki/Batch_files">batch file</a> is best avoided and how to characterize better solutions in terms of it.</p>
<p>Although Visual Studio, in tandem with the <a href="http://en.wikipedia.org/wiki/Msbuild">MSBuild engine</a>, generally takes good care of compilation, I rarely want to rely on it solely. Instead, I’d prefer that any developer task be easily run from the command-line. This ensures that no magic is going on, that the task is kept simple and flexibility, and that it doesn’t rely on Visual Studio to work. The challenge, however, is which of the many tools available to pick. It must be one that’s flexible enough to meet most requirements with relative ease or the automation will likely not be a valid documentation medium in itself.</p>
<h4>Why not to use Windows batch files</h4>
<p>As a general example, consider the deployment of a <a href="http://www.bugfree.dk/blog/2010/03/31/getting-started-with-sharepoint-presentation">SharePoint 2007 solution</a>. With SharePoint a good deal more than compiling is needed to bring new functionality into a SharePoint installation. Whereas Visual Studio and MSBuild may still compile the code and <a href="http://wspbuilder.codeplex.com">WSPBuilder</a> create the WSP installation package, both from within Visual Studio and from the command-line, getting everything setup cries for automation, even locally. A common approach (possibly inspired by <a href="http://www.amazon.com/Microsoft-Windows-SharePoint-Services-Developer/dp/0735623201/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1285960936&amp;sr=8-1">popular</a> SharePoint 2007 literature) is that of the batch file applying various operations to a WSP. For the sake of brevity, I&#8217;ve kept the example short, but imagine extending it with a check-out source code task, a compilation task, a WSPBuilder task, and a feature deactivation and activation task, and possibly a warm-up task. Add to this a master script that orchestrate the whole thing. In the end, I’d end up with scripts that become increasingly harder to maintain as they grow in number and size.</p>
<pre class="prettyprint lang-sh">@set STSADM=&quot;c:\program files\common files\microsoft shared\web server extensions\12\bin\stsadm&quot;

if &quot;%1&quot; == &quot;uninstall&quot; goto uninstall
if &quot;%1&quot; == &quot;install&quot; goto install
if &quot;%1&quot; == &quot;&quot; goto reinstall

:uninstall
    %STSADM% -o retractsolution -name Foo.wsp -immediate
    %STSADM% -o execadmsvcjobs
    %STSADM% -o deletesolution -name Foo.wsp -override
    goto end

:install  
    %STSADM% -o addsolution -filename Foo.wsp
    %STSADM% -o deploysolution -name Foo.wsp -immediate -allowGacDeployment -force
    %STSADM% -o execadmsvcjobs
    goto end

:reinstall
    call Foo uninstall
    call Foo install
    goto end
	
:end</pre>
<p>Still, because of the ubiquitous nature of command.com and cmd.exe, the batch file interpreters, batch files are everywhere. Regardless that the technology is a left-over from the days of MS DOS and haven&#8217;t evolved much since. Not only are the branching and looping constructs limited, so are the <a href="http://technet.microsoft.com/en-us/library/dd560674(WS.10).aspx">available commands</a>. Suppose I want to find out if a command was indeed successful. This turns out to be really hard when all I have to work with is the <a href="http://en.wikipedia.org/wiki/Errorlevel">errorlevel</a> of the most recently executed command. Assuming the command adheres to the errorlevel convention, for the script to fail as early and as close to the real error as possible, I’d have to inspect the property after each command, causing the batch file to grow quite verbose. Sadly, batch files lack the equivalent of <a href="http://www.davidpashley.com/articles/writing-robust-shell-scripts.html#id2399158">set -o errexit</a> of <a href="http://en.wikipedia.org/wiki/Bash_(Unix_shell)">Bash</a>, where the interpreter checks for success after each command and aborts immediately on error. Relying solely on the errorlevel is oftentimes insufficient anyway. To determine success, I’d typically have to parse actual command output or inspect some system property by downloading additional commands or building my own.</p>
<h4>Essential vs. incidental requirements</h4>
<p>Unless I plan to sit idle and stare at the screen and be a human error detector while the batch file run, I think it’s safe to say that it’s mostly unsuitable for developer automation. Hence in late 2005 I <a href="http://www.bugfree.dk/blog/2006/01/04/being-a-functional-pythonian">rolled my own automation tool in Python</a>. With Python or Ruby or a similar dynamic language acting as the glue that ties everything together, almost any task can be automated in a robust way. Of course, I could also automate with a static language like C# (it&#8217;s surprisingly common). But for script-like tasks, I don’t particularly fancy the long cycle of editing source code in Visual Studio, compiling it, deploying it, and having a hard time debugging it in environment without Visual Studio. A dynamic language, on the other hand, short-circuits the development cycle and allows for interactive programming through a <a href="http://en.wikipedia.org/wiki/REPL">REPL</a>.</p>
<p>With a dynamic language that interacts with .NET, such as <a href="http://en.wikipedia.org/wiki/Ironpython">IronPython</a>, <a href="http://en.wikipedia.org/wiki/IronRuby">IronRuby</a>, or <a href="http://en.wikipedia.org/wiki/Powershell">Powershell</a>, possibly with supporting DSLs like <a href="http://www.blueskyonmars.com/projects/paver">Paver</a>, <a href="http://en.wikipedia.org/wiki/Rake_(software)">Rake</a>, or <a href="http://en.wikipedia.org/wiki/Psake">psake</a> on top, the need for writing custom commands to interact with the operating system or the application almost vanishes. The question, then, is which of the dynamic languages to go with when at their technical core they’re so much alike. Besides sharing the concept of a REPL, the notion of a tuple, a list, a map, and operations on each are baked into their syntax, making code quite terse. It even makes it convenient to express any configuration in the language itself and not in XML where I’d first have to come up with a schema, and then create an instance of it before parsing it. On Windows, however, Powershell is gradually becoming the next ubiquitous interpreter, with applications shipping with cmdlets, whereas IronPython or IronRuby is a separate download.</p>
<h4>Conclusion</h4>
<p>No matter the tool, what I end up doing is defining tasks, form dependencies between tasks, and have the tool execute tasks in an order that satisfies their dependencies. As the tool traverses the dependency graph and executes tasks, it’s up to each task to detect success, and up to the tool to report on progress. A good tool is therefore characterized by the ease with which I can express these things, the available language constructs, the ease of debugging, and the tool’s ability to converse in foreign languages.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2010/09/26/essential-requirements-for-a-developer-automation-tool/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Coders at work</title>
		<link>http://www.bugfree.dk/blog/2010/09/05/coders-at-work/</link>
		<comments>http://www.bugfree.dk/blog/2010/09/05/coders-at-work/#comments</comments>
		<pubDate>Sun, 05 Sep 2010 08:33:00 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Book]]></category>
		<category><![CDATA[History]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1035</guid>
		<description><![CDATA[Since I very much enjoyed Peter Seibel’s Practical Common Lisp, I was looking forward to Coders at work. Written entirely using a question and answer format it’s an unconventional read. But after a couple of interviews the format, inspired by Programmers at work, begins to feel more natural. The book tells the story of 15 [...]]]></description>
			<content:encoded><![CDATA[<p>Since I very much enjoyed <a href="http://www.gigamonkeys.com">Peter Seibel</a>’s <a href="http://www.gigamonkeys.com/book/">Practical Common Lisp</a>, I was looking forward to <a href="http://www.amazon.com/Coders-at-Work-Peter-Seibel/dp/1430219483/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1283607343&amp;sr=8-1">Coders at work</a>. Written entirely using a question and answer format it’s an unconventional read. But after a couple of interviews the format, inspired by <a href="http://www.amazon.com/dp/1556152116">Programmers at work</a>, begins to feel more natural.</p>
<p>The book tells the story of 15 prominent coders by asking each coder roughly the same questions. After covering their initial exposure to programming, it moves on to how they design and debug programs and whether or not they use <a href="http://en.wikipedia.org/wiki/Literate_programming">literate programming</a> or <a href="http://en.wikipedia.org/wiki/Design_by_contract">design by contract</a> or more formal proof techniques. In my opinion, each interview varies too little and is backed by too many anecdotes. I’d hoped for more universal wisdom and advice that would transcend time and technologies.</p>
<p>Perhaps not too surprisingly, during the interviews you learn how many of the coders got into the field entirely by chance. <a href="http://en.wikipedia.org/wiki/Simon_Peyton_Jones">Simon Peyton Jones</a>, a creator of <a href="http://haskell.org">Haskell</a>, was drawn to electrical and software engineering because he found math too hard and competitive. Others were lucky enough that their school happened to have a mainframe sitting in the basement for them to tinker with. On the whole, computers simply sparked an early and lifelong passion.</p>
<p>Another common coder’s trait seems to be that of code reading. As an individual developer, you should improve by studying real code of every quality. As a team of developers, you should improve by shared code reviews of what you’re building. Like no other technique, studying and reviewing code will help share knowledge and improve general developer skills. Yet, the typical organization keeps to in-house presentations on the vNext features of some product and calls it knowledge sharing for developers.</p>
<p>I ought to do more a la Scott Hanselman’s <a href="http://www.hanselman.com/blog/CategoryView.aspx?category=Source+Code">weekly source code</a>. When taking on C++ and <a href="http://en.wikipedia.org/wiki/Microsoft_Foundation_Class_Library">MFC</a> in the late nineties, I remember reading the MFC sources and admiring how well it applied design patterns and design by contract to the C-based Windows API. That code base alone had a profound impact on my understanding of object-orientation and how to write code.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2010/09/05/coders-at-work/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unit testing LINQ to SQL using TypeMock</title>
		<link>http://www.bugfree.dk/blog/2010/05/04/unit-testing-linq-to-sql-using-typemock/</link>
		<comments>http://www.bugfree.dk/blog/2010/05/04/unit-testing-linq-to-sql-using-typemock/#comments</comments>
		<pubDate>Tue, 04 May 2010 19:23:00 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Tool]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1050</guid>
		<description><![CDATA[Recent months have brought about a proliferation of mocking frameworks that mocks what more traditional framework like Rhino Mocks cannot. Instead of creating and loading a mock implementation at runtime, the new breed of mocking frameworks hooks into the CLR to intercept and redirect calls. This opens up virtually every aspect of a class to [...]]]></description>
			<content:encoded><![CDATA[<p>Recent months have brought about a proliferation of mocking frameworks that mocks what more traditional framework like <a href="http://www.ayende.com/projects/rhino-mocks.aspx">Rhino Mocks</a> cannot. Instead of creating and loading a mock implementation at runtime, the new breed of mocking frameworks hooks into the CLR to <a href="http://www.bugfree.dk/blog/2009/02/11/an-example-of-unit-testing-using-typemock">intercept and redirect calls</a>. This opens up virtually every aspect of a class to mocking, which is useful for testing code not written with explicit testability in mind. Until recently, <a href="http://site.typemock.com/typemock-isolator-product">TypeMock</a> was the only mocking framework around that took the latter approach, but it’s now being challenged by <a href="http://research.microsoft.com/en-us/projects/moles">Moles</a> from Microsoft Research and <a href="http://www.telerik.com/products/mocking.aspx">JustMock</a> from Telerik.</p>
<h4>Why traditional dependency-breaking techniques come short</h4>
<p>After watching a screencast on how to <a href="http://www.dimecasts.net/Casts/CastDetails/170">use Moles to unit test LINQ to SQL</a> without hitting the database, I thought it would be interesting to do the same with TypeMock. But first, let’s make sure we understand why traditional dependency-breaking techniques come short in testing LINQ to SQL. Assuming we want to put a repository under test, our goal is to mock how it accesses the database. Here’s a simple implementation of a repository that queries the Employee table of the <a href="http://sqlserversamples.codeplex.com">AdventureWorks</a> database:</p>
<pre class="prettyprint lang-cs">public class EmployeeRepository {
    public List&lt;Employee&gt; GetEmployeesByHireDate(DateTime start, DateTime end) {
        using (var ctx = new AdventureWorksDataContext())
            return (from e in ctx.Employees
                    where e.HireDate &gt;= start &amp;&amp; e.HireDate &lt;= end
                    select e).ToList();
    }
}
</pre>
<p>All calls to the database are routed through the AdventureWorksDataContext generated by Visual Studio. To mock access to the database, we therefore have to mock part of the data context. Easier said than done, though, for the context doesn’t expose an interface that a fake can implement. In addition, the tables are accessed through properties on the context that return a type of <a href="http://msdn.microsoft.com/en-us/library/bb358844">Table&lt;TEntity&gt;</a>. Unfortunately, the constructor of Table&lt;TEntity&gt; is internal and the class itself is sealed, eliminating the hope of instantiating or subclassing the type by traditional means:</p>
<pre class="prettyprint lang-cs">public sealed class Table&lt;TEntity&gt; : IQueryProvider, 
        ITable, IListSource, ITable&lt;TEntity&gt;, IQueryable&lt;TEntity&gt;, 
        IEnumerable&lt;TEntity&gt;, IQueryable, IEnumerable
        where TEntity : class {
    internal Table(DataContext context, MetaTable metaTable) {
        ...
    }
}</pre>
<p>For an example of how the data context itself creates an instance of Table&lt;TEntity&gt;, take a look at the Employees property on the AdventureWorksDataContext. It relies on the GetTable&lt;Employee&gt; method on the DataContext class to create an instance of Table&lt;Employee&gt;. Despite its constructors being internal, the GetTable&lt;TEntity&gt; method has no trouble constructing an instance of the Table&lt;TEntity&gt; type, as they both reside in the System.Data.Linq assembly:</p>
<pre class="prettyprint lang-cs">public partial class AdventureWorksDataContext : DataContext {
    public Table&lt;Employee&gt; Employees {
        get {
            return GetTable&lt;Employee&gt;();
        }
    }
}</pre>
<h4>How to break the unbreakable</h4>
<p>The design of LINQ to SQL leaves us short of a traditional testing seam, as <a href="http://www.amazon.com/Working-Effectively-Legacy-Robert-Martin/dp/0131177052">Michael Feathers</a> would phrase it; a place at which we can alter the behavior of a program without editing in that place. This explains why, with LINQ to SQL, traditionally we’ve had to test against a real database with all its constraints, making our tests brittle, slow, and painful to write and maintain. With the new breed of mocking frameworks the issues of not being able to subclass or not being able to call an internal constructor go away (and new issues take their place). Regardless, here’s how to write a unit test for the CustomerRepository that doesn’t hit the database:</p>
<pre class="prettyprint lang-cs">[TestClass]
public class CustomerRepositoryTest {
    private EmployeeRepository _repository;

    [TestInitialize]
    public void Initialize() {
        _repository = new EmployeeRepository();

        var fakeEmployees = new List&lt;Employee&gt; {
            new Employee {EmployeeID = 1, HireDate = new DateTime(2004, 12, 1)},
            new Employee {EmployeeID = 2, HireDate = new DateTime(2006, 7, 1)},
            new Employee {EmployeeID = 3, HireDate = new DateTime(2009, 3, 1)}
        }.AsQueryable();

        var fakeDataContext = Isolate.Fake.Instance&lt;AdventureWorksDataContext&gt;();
        Isolate.Swap.NextInstance&lt;AdventureWorksDataContext&gt;().With(fakeDataContext);

        // var fakeEmployeeTable = Isolate.Fake.Instance&lt;Table&lt;Employee&gt;&gt;();
        // Isolate.WhenCalled(() =&gt; fakeDataContext.Employees).WillReturn(fakeEmployeeTable);
        // Isolate.WhenCalled(() =&gt; fakeEmployeeTable).WillReturnCollectionValuesOf(fakeEmployees);
        // or by transitivity
        Isolate.WhenCalled(() =&gt; fakeDataContext.Employees).WillReturnCollectionValuesOf(fakeEmployees);
    }
        
    [TestMethod]
    public void GetEmployeesByHireDate_should_return_hires_from_2008_until_present() {
        var employees = _repository.GetEmployeesByHireDate(new DateTime(2008, 1, 1), DateTime.Now);
        Assert.AreEqual(1, employees.Count());
        Assert.AreEqual(3, employees[0].EmployeeID);
    }
}
</pre>
<p>The test method itself looks exactly as if we’d been testing against a real database. The difference lies in the Initialize method, where we setup the fake data context and database contents. We instruct TypeMock to return the fake context in place of the real one inside EmployeeRepository. And whenever someone calls the Employees property on the fake context, we have TypeMock intercept the call and return a fake collection of type <a href="http://msdn.microsoft.com/en-us/library/bb351562.aspx">IQueryable&lt;Employee&gt;</a>. We could’ve returned an instance of Table&lt;Employee&gt;, which implements IQueryable&lt;Employee&gt;, but in this case returning the collection is simpler and sufficient. Had we had more methods on our repository, we likely would’ve added additional rows to the Employee table and populated more of its columns.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2010/05/04/unit-testing-linq-to-sql-using-typemock/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The given-expect testing pattern</title>
		<link>http://www.bugfree.dk/blog/2010/04/25/the-given-expect-testing-pattern/</link>
		<comments>http://www.bugfree.dk/blog/2010/04/25/the-given-expect-testing-pattern/#comments</comments>
		<pubDate>Sun, 25 Apr 2010 20:31:58 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Asp.Net]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1047</guid>
		<description><![CDATA[I was watching Brett Schuchert’s TDD screencast on implementing the shunting yard algorithm in C#. In it Brett builds up his tests in a style I hadn’t come across before. Each test is expressed as a given-expect statement. A pattern that is particularly useful in situations in which a class has a main method that [...]]]></description>
			<content:encoded><![CDATA[<p>I was watching <a href="http://schuchert.wikispaces.com">Brett Schuchert</a>’s TDD <a href="http://vimeo.com/album/210446">screencast</a> on implementing the <a href="http://en.wikipedia.org/wiki/Shunting-yard_algorithm">shunting yard algorithm</a> in C#. In it Brett builds up his tests in a style I hadn’t come across before. Each test is expressed as a given-expect statement. A pattern that is particularly useful in situations in which a class has a main method that accepts an open-ended number of dissimilar inputs.</p>
<p>I found the given-expect pattern useful in testing a piece of code that I was working on this week. I was refactoring and adding tests around an ASP.NET control adapter that makes SharePoint 2007 pages more XHTML compliant. I wanted to reuse the transformations outside the control adapter and hence ended up moving the transformation logic to a new class. It accepts possibly malformed HTML and relies on heuristics of the <a href="http://htmlagilitypack.codeplex.com">HTML Agility Pack</a> to build a DOM off of it. I can then query the DOM, looking for known violations, and patch them before returning XHTML to the caller.</p>
<pre class="prettyprint lang-cs">public class HtmlToXHtmlTransformer {
    private readonly HtmlDocument _document;

    public HtmlToXHtmlTransformer(string html) {
        _document = new HtmlDocument();
        _document.DetectEncoding(new StringReader(html));
        _document.LoadHtml(html);
    }

    private void Transform(string xpath, Action&lt;HtmlNode&gt; nodeMatch) {
        var nodes = _document.DocumentNode.SelectNodes(xpath);
        if (nodes != null)
            foreach (var node in nodes)
                nodeMatch.Invoke(node);
    }

    private void FixDuplicateBorderAttributeOnSPGridViewControl() {
        Transform(&quot;//table[count(@border)=2]&quot;, node =&gt; node.Attributes.Remove(&quot;border&quot;));
    }

    public string Transform() {
        FixDuplicateBorderAttributeOnSPGridViewControl();
        _document.OptionWriteEmptyNodes = true;
        return _document.DocumentNode.WriteTo(); 
    }        
}</pre>
<p>The complete HtmlToXHtmlTransformer collects a dozen transformations. Its Transform method is what we want to call with various HTML fragments to verify that they come out as XHTML. For this purpose, we might do the tests as <a href="http://msdn.microsoft.com/en-us/library/ms182527.aspx">Visual Studio data-driven tests</a> that read their input and output from a text file. But in most cases I prefer traditional tests, so I can describe the purpose of a test with a descriptive method name and possibly a comment.</p>
<pre class="prettyprint lang-cs">     
[TestClass]
public class HtmlToXHtmlTransformerTest {
    private string _result;

    [TestMethod]
    public void Must_selfclose_nodes_when_allowed() {
        Given(&quot;&lt;br&gt;&quot;);
        Expect(&quot;&lt;br /&gt;&quot;);
    }

    [TestMethod]
    public void Must_remove_duplicate_border_on_SPGridView_control {
        Given(@&quot;&lt;table border=&quot;&quot;0&quot;&quot; border=&quot;&quot;0&quot;&quot;&gt;&lt;/table&gt;&quot;);
        Expect(@&quot;&lt;table border=&quot;&quot;0&quot;&quot;&gt;&lt;/table&gt;&quot;);
    }

    private void Expect(string xhtml) {
        Assert.AreEqual(xhtml, _result);
    }

    private void Given(string html) {
        var transformer = new HtmlToXHtmlTransformer(html);
        _result = transformer.Transform();
    }
}</pre>
<p>I particularly like the clarity of the given-expect pattern and find that for a reasonable number of tests it’s a viable alternative to data-driven test. I do, however, recognize the value of data-driven tests in situations where a non-developer wants to test a class. Though at the unit test level I’ve never experienced this. It’s more characteristic of <a href="http://en.wikipedia.org/wiki/FitNesse">FitNesse for acceptance testing</a>. However you unit test, just make sure your tests run with a minimum of effort on your part and that they run fast.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2010/04/25/the-given-expect-testing-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Configuring Emacs through Emacs Lisp</title>
		<link>http://www.bugfree.dk/blog/2010/04/15/configuring-emacs-through-emacs-lisp/</link>
		<comments>http://www.bugfree.dk/blog/2010/04/15/configuring-emacs-through-emacs-lisp/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 20:50:02 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Emacs]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1046</guid>
		<description><![CDATA[I’ve been an Emacs fanboy for close to 15 years. For a long time I used Emacs solely on Linux because of it’s ubiquity. But written in C and Emacs Lisp, Emacs has great cross-platform support, and now I use it daily on Windows too. Installing Emacs on Windows is as straightforward as downloading and [...]]]></description>
			<content:encoded><![CDATA[<p>I’ve been an Emacs fanboy for close to 15 years. For a long time I used Emacs solely on Linux because of it’s ubiquity. But written in C and <a href="http://en.wikipedia.org/wiki/Emacs_Lisp">Emacs Lisp</a>, Emacs has great cross-platform support, and now I use it daily on Windows too. <a href="http://www.gnu.org/software/emacs/windows/Getting-Emacs.html">Installing Emacs</a> on Windows is as straightforward as downloading and extracting the <a href="http://ftp.gnu.org/gnu/emacs/windows/">most recent Zip file</a>.</p>
<h4>Code equals data</h4>
<p>Configuring the editor is done by placing Emacs Lisp code in the .emacs file. Whenever Emacs starts, it looks for this file in the directory specified by the HOME environment variable and executes its content. Unlike the XML configuration files of .NET and Java, with Emacs there’s no intermediate configuration format. There’s no extra language to learn and no limitation in the expressiveness of the configuration language. With this interchangeability of code and data, every behavior of Emacs can be hooked into and tailored and every global variable redefined.</p>
<h4>Starting Emacs from the Windows taskbar</h4>
<p>On my machine, I like everything Emacs-related to reside in the directory that I extracted Emacs to, yet I want to be able to start Emacs from the taskbar. I do this by pinning cmd.exe to the taskbar and modifying its destination so it defines HOME for this instance before spawning Emacs. This way the HOME of Emacs doesn’t conflict with the HOME of other applications.</p>
<pre>    cmd.exe /C &quot;set HOME=...\emacs-23.1&amp;&amp;...\emacs-23.1\bin\runemacs.exe&quot;</pre>
<p>My .emacs isn’t too esoteric. Nevertheless, here it is for posterity. Reading on, keep in mind that unless otherwise noted, all referenced packages come with Emacs 23.1.</p>
<h4>General settings</h4>
<p>I start off redefining a couple of global variables. Much functionality relies on the user name and mail address to be known in advance. I then remove the toolbar at the top of the Emacs window, because I use menus or keyboard shortcuts anyway. Next I disable the splash screen on startup, and redefine a few global variables governing Emacs’ scrolling behavior. By default scrolling isn’t line by line, but chuck by chuck of text. I find this behavior confusing.</p>
<pre>(setq user-full-name &quot;Ronnie Holm&quot;)
(setq user-mail-address &quot;foo@bar.baz&quot;)

(tool-bar-mode nil)                            ;; don't show the toolbar

(setq inhibit-startup-message t                ;; don't show ...
      inhibit-startup-echo-area-message t)     ;; ... startup messages

(setq scroll-margin 1                          ;; do smooth scrolling
      scroll-conservatively 100000
      scroll-up-aggressively 0.01
      scroll-down-aggressively 0.01)</pre>
<p>Next I turn on automatic syntax highlighting and commands specific to known file types. Following that I turn the blinking square cursor into a solid and less distracting one. Also, I instruct Emacs not to retain backups of files that I edit or save. I don’t discount the value of backups, but I also don’t like having to remove backup and auto-save files when they clutter my folders. Instead&#160; Emacs should move these files to the Windows Recycle Bin. Lastly, I enable <a href="http://www.gnu.org/software/emacs/manual/html_node/emacs/Iswitchb.html">iswitchb-mode</a>, which makes switching buffers easier by providing on-the-fly suggestions.</p>
<pre>(global-font-lock-mode t)                      ;; always do syntax highlighting
(blink-cursor-mode 0)                          ;; don't blink cursor
(setq backup-inhibited t)                      ;; no backup files
(setq delete-by-moving-to-trash t)             ;; delete moves to recycle bin
(iswitchb-mode t)                              ;; easy buffer switching</pre>
<p>The last of the general settings involve modifications to the modeline at the bottom of the Emacs window. By default it displays the buffer name, the line number, and the modes Emacs is in. I extend the modeline with the column cursor position and the size of the current buffer.</p>
<pre>(column-number-mode t)                         ;; show column numbers
(size-indication-mode t)                       ;; show file size</pre>
<h4>Package settings</h4>
<p>Oftentimes I find myself editing the same set of files every day. So having the cursor move to where I left it editing the file the last time is handy. This is done by <a href="http://www.emacswiki.org/cgi-bin/wiki/SavePlace">save-place mode</a>. Behind the scenes it stores a file name/offset mapping in a file below HOME.</p>
<pre>(setq save-place-file &quot;~/.emacs.d/saveplace&quot;)  ;; location of saveplace file
(setq-default save-place t)                    ;; activate for all buffer
(require 'saveplace)</pre>
<p>As hinted by <a href="http://www.bugfree.dk/blog/2009/11/05/getting-organized-with-emacs-org-mode/">Getting organized with Emacs Org-mode</a>, I very much enjoy using <a href="http://orgmode.org">Org-mode</a> for keeping notes, maintaining lists, and much more. The next section of my .emacs is therefore dedicated to customizing org-mode. Firstly, to make documents easier to read, instead of displaying all the asterisks that designate an indentation level, only display the last one. Secondly, align each indentation level by always adding two asterisks on indentation. Thirdly, when clocking time, have Emacs remember what I was doing and for how long across restarts. But remove clocked time less than one minute.</p>
<pre>(setq org-hide-leading-stars t)                ;; hide but one star in outline
(setq org-add-levels-only t)                   ;; align items nicely
(setq org-clock-persist t)                     ;; keep track of time ...
(org-clock-persistence-insinuate)              ;; ... across sessions
(setq org-clock-out-remove-zero-time-clocks t) ;; remove 0-duration clocked</pre>
<p>The default Emacs color theme looks kind of dull. So I downloaded the <a href="http://www.emacswiki.org/emacs/ColorTheme">color-theme</a> package and selected a more aesthetically pleasing theme. After downloading color-theme, place its Lisp files in ~/site-lisp. That’s one of the places where Emacs will automatically look for packages. The 300 or so packages that come with Emacs are in the ~/lisp folder.</p>
<pre>(require 'color-theme)                         ;; use a color theme
(color-theme-initialize)
(color-theme-arjen)</pre>
<p>My last additions to .emacs involve Haskell. Emacs doesn’t support Haskell out-of-the-box. But a <a href="http://www.haskell.org/haskell-mode">haskell-mode</a> is available for download. It turns Emacs into a decent Haskell development environment. Besides syntax highlighting and code formatting capabilities, it adds to Emacs commands for interacting with the Haskell compiler and Haskell interactive.</p>
<pre>(load &quot;~/site-lisp/haskell-mode-2.6.4/haskell-site-file&quot;)
(add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)
(add-hook 'haskell-mode-hook 'turn-on-haskell-indentation)</pre>
<p>This concludes my .emacs. Quite a few of these settings I picked up reading the <a href="http://emacs-fu.blogspot.com">emacs-fu</a> blog.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2010/04/15/configuring-emacs-through-emacs-lisp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SharePoint Saturday EMEA virtual conference</title>
		<link>http://www.bugfree.dk/blog/2010/04/04/sharepoint-saturday-emea-virtual-conference/</link>
		<comments>http://www.bugfree.dk/blog/2010/04/04/sharepoint-saturday-emea-virtual-conference/#comments</comments>
		<pubDate>Sun, 04 Apr 2010 18:08:00 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Conference]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1042</guid>
		<description><![CDATA[Back in January, I attended the one-day virtual SharePoint Saturday EMEA conference. It was my first virtual conference so I was excited to see how it would work out. Presenting through Office Live Meeting and interacting with the audience through text-only is definitely a challenge compared to live presentations. But I’d say it went well [...]]]></description>
			<content:encoded><![CDATA[<p>Back in January, I attended the one-day virtual <a href="http://www.sharepointsaturday.org/emea/default.aspx">SharePoint Saturday EMEA conference</a>. It was my first virtual conference so I was excited to see how it would work out. Presenting through Office Live Meeting and interacting with the audience through text-only is definitely a challenge compared to live presentations. But I’d say it went well with 50-60 attendees at each of the three parallel tracks.</p>
<p>Here’re the talks that I attended, all <a href="http://www.endusersharepoint.com/2010/02/19/sharepoint-saturday-emea-20-hours-of-recordings-available">recorded and available with slides</a>.</p>
<h4>SharePoint 2010 Planning and Best Practice Approaches to Upgrade</h4>
<p>Upgrading to SharePoint 2010, you should first establish a copy of your existing environment on the latest patch level. Then run the stsadm command with the new PreUpgradeChecker option. Make sure your environment has no unused features, site templates, and so on, and identify everything that has changed from out-of-the-box by running a tool like <a href="http://winmerge.org">WinMerge</a> on the 12 hive. Also, assert that no pages has been ghosted, and don’t attempt to upgrade your SharePoint 2007 master page. Start with the 2010 ones and add in your 2007 modifications. SharePoint 2010 ships with both 2007 and 2010 master pages, but SharePoint 2007 and 2010 isn’t binary compatible. </p>
<p>Make sure all <a href="http://blogs.msdn.com/sharepoint/archive/2009/05/07/announcing-sharepoint-server-2010-preliminary-system-requirements.aspx">hardware requirements</a> are satisfied: 8 GB RAM at the minimum on the Windows 2008 servers running SharePoint and MS SQL Server. On the client you need Internet Explorer 7 or 8 or Firefox 3.x to author content. Internet Explorer 6 isn’t supported. Not even with a degraded reader experience. The <a href="http://msdn.microsoft.com/en-us/library/ee554869%28office.14%29.aspx">SharePoint 2010 development environment</a> should be setup with Visual Studio 2010 on Windows Vista or Windows 7 in order to compile, debug, build, and deploy right out of Visual Studio 2010. </p>
<h4>Understanding, using, and customizing PowerShell for a SharePoint 2010 Environment</h4>
<p>This talk started with some PowerShell history and basics. PowerShell is made up of a shell that executes commands and an integrated scripting environment for development. .NET compiled code, called cmdlets, are the executable units combined using the PowerShell pipeline. The PowerShell language itself is dynamic and loosely typed, so being able to express yourself tops performance. Scripts may be compiled and deployed as a SnapIn, consisting of compiled DLLs and registry updates, or as a module using xcopy deployment.</p>
<p>SharePoint 2010 ships with 650 cmdlets, and its own base class for writing additional SharePoint cmdlets.</p>
<h4>Design and Manage Site Collections in SharePoint 2010</h4>
<p>By default every single site collection within a web application goes into one rapidly growing database (think about users migrating from file shares to site collections). Such a large database takes time to backup and restore. Hence, with SharePoint 2010, consider partitioning site collections into their own databases from the beginning. After a database is created, map it to one and only one site collection. Then, instead of putting a size limit on the web application, put it on the site collection itself.</p>
<p>In SharePoint 2007 you had to create multiple Shared Service Providers (SSP) if site collections had different needs or you didn’t want a site collection to access parts of an existing SSP. With SharePoint 2010, application services can now be shared between site collections.</p>
<p>With sandbox solutions, the solution is deployed to the database hosting the site, rather than to front-end servers. This makes it easier to deploy code, but the code is limited in what it can do, and you may have to set resource quotas across the site collection.</p>
<h4>SharePoint 2010, Getting Ready</h4>
<p>This talk provided an overview of SharePoint 2010. WSS 3.0 becomes SharePoint Foundation 2010 and MOSS 2007 becomes SharePoint Server 2010. Business Connectivity Services (BCS) are no longer part of the server edition, but has been moved to Foundation. A lot more services have been added, like state service, usage and health service, and Visio graphics service. Generally, with all the improvements to deployment and upgrade with PowerShell and the addition of multi-tenancy for the SSP, SharePoint 2010 is better in a hosting scenario. </p>
<p>The web user interface has been made more Office-like with the addition of the ribbon and the use of AJAX. In document libraries you can create document sets as a way to relate documents to each other and have versioning and workflow follow every document in the set. Through the BCS, you can expose external data as native SharePoint lists with full CRUD capabilities.</p>
<h4>SharePoint 2010 Development Tips and Tricks</h4>
<p>The focus of the first part this talk is on the SharePoint 2010 Foundation features. Instead of developing against the web services or the object model, you can use the new managed client object model. This way, you can work against SharePoint from .NET code, from a Silverlight application, or from JavaScript. Behind the scenes, the client object model works against a WCF service running on the SharePoint server, which talks to the server object model on the server, and returns JSON to the client. </p>
<p>The second part of this talk is about sandbox solutions. This feature provides site collection users with the ability to upload and deploy WSPs. Finally, the third part of the talk is about the fluid integration model, which solves the problem of accessing cross-domain resources, e.g., having a Silverlight application access information on a SharePoint server on a different domain. </p>
<h4>Installing and Configuring SharePoint Server 2010 in a Virtual Environment</h4>
<p>This talk recommends that everyone read the MS whitepaper on <a href="http://download.microsoft.com/download/D/A/8/DA82C84A-1C3F-418A-BCC7-8A38CBBC1935/Virtualization_of_SharePoint_Products_and_Technologies_White_Paper_-_final1.docx">Virtualization of Microsoft SharePoint Products and Technologies</a>. Configuring a development environment, the dilemma is weather to create one virtual machine hosting everything or one virtual machine for the MS SQL Server, the Active Directory, and the SharePoint server each. The presenter suggests a middle ground. Still, it’s important to create a number of service accounts and use them in your development environment rather than running everything as administrator.</p>
<p>The SharePoint 2010 installer comes with a prerequisite installer that goes onto the web and downloads required software. After that, you can run the SharePoint server installer. Here you can choose between Standalone and Server farm, but always pick server farm. Standalone should only be used for demo purposes.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2010/04/04/sharepoint-saturday-emea-virtual-conference/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting started with SharePoint presentation</title>
		<link>http://www.bugfree.dk/blog/2010/03/31/getting-started-with-sharepoint-presentation/</link>
		<comments>http://www.bugfree.dk/blog/2010/03/31/getting-started-with-sharepoint-presentation/#comments</comments>
		<pubDate>Wed, 31 Mar 2010 11:31:05 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Asp.Net]]></category>
		<category><![CDATA[Presentation]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2010/03/31/getting-started-with-sharepoint-development/</guid>
		<description><![CDATA[Download slides from the presentation. Last week at work I did a 45 minutes presentation on how to get started with SharePoint development. Instead of the usual presentation on the technical merits of SharePoint, my focus was more on the change in mindset required coming from ASP.NET. For even though ASP.NET is a cornerstone of [...]]]></description>
			<content:encoded><![CDATA[<p>Download <a href="http://www.bugfree.dk/blog/wp-content/uploads/2010/03/GettingStartedWithSharePoint.pdf">slides</a> from the presentation.</p>
<p>Last week at work I did a 45 minutes presentation on how to get started with SharePoint development. Instead of the usual presentation on the technical merits of SharePoint, my focus was more on the change in mindset required coming from ASP.NET. For even though ASP.NET is a cornerstone of SharePoint, SharePoint is so much more. Not to mention different.</p>
<h4>History makes a difference</h4>
<p>SharePoint is a <a href="http://blogs.msdn.com/joelo/archive/2007/12/28/7-years-of-sharepoint-a-history-lesson.aspx">long-evolving</a> product, dating back to <a href="http://www.joiningdots.net/blog/2006/08/sharepoint-history.html">the late nineties</a>. From its <a href="http://blogs.msdn.com/sharepoint/archive/2009/10/05/sharepoint-history.aspx">inception and up till now</a> new technologies have replaced old ones, APIs have emerged and died, product teams have merged, and Microsoft have bought and integrated other companies’ products into SharePoint. At the same time SharePoint has become the fastest growing server product in Microsoft history. All of this inevitably leaves its marks on the APIs, which aren’t as consistent and defect free as we’re used to with the .NET framework.</p>
<h4>Provisioning is the magic sauce</h4>
<p>What truly makes SharePoint development different from ASP.NET is the notion of provisioning. With ASP.NET you create a bunch of ASPX files, organize them in a static file structure, and deploy them to a server. With SharePoint, the structure emerges over time as SharePoint or the user creates instances of templates: sites from site templates, lists from list templates, pages from page templates, and so forth. From a developer’s perspective the challenge isn’t the instance creation in itself. It’s that SharePoint encourages users to not only dynamically evolve the structure, but also to modify the instances, severing their definition from the template. While it empowers users, it also makes it challenging to programmatically evolve the structure.</p>
<p>Developing with SharePoint is about creating templates and components for SharePoint or the user to compose a site of. To make this composition work, SharePoint imposes constraints on what can be done and how. While any constraint may at times be perceived as a hindrance, accepting it is what guarantees that a components will play nicely with others. These pieces of functionality are then packaged as features and added to a WSP installation file for deployment to SharePoint. Features may then be activated, making their functionality available to a site. Or deactivated and the WSP uninstalled.</p>
<h4>Why learn SharePoint</h4>
<p>By the end of the day, no doubt SharePoint is more challenging to work with than ASP.NET. Not acknowledging its history makes many ASP.NET developers so frustrated that they’ll never again want to work with SharePoint. Coming from ASP.NET I can understand why. At times SharePoint isn’t as smooth and evolved as ASP.NET. But knowing what to expect takes the worst of the frustration. And once you learn to leverage the power of SharePoint, you can build applications without writing a lot of plumping code. To a large extend the architecture is given, leaving you with the opportunity to fill in the blanks.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2010/03/31/getting-started-with-sharepoint-presentation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SharePoint list access using the Repository pattern</title>
		<link>http://www.bugfree.dk/blog/2010/01/18/sharepoint-list-access-using-the-repository-pattern/</link>
		<comments>http://www.bugfree.dk/blog/2010/01/18/sharepoint-list-access-using-the-repository-pattern/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 20:11:58 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Pattern]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1040</guid>
		<description><![CDATA[(Download code here. See related post on SharePoint list definition using the Template pattern) Maybe it’s that the SharePoint API is hard to use. Maybe it’s that coding against SharePoint is about making smaller additions here and there. Maybe it’s that the Patterns &#38; Practices SharePoint Guidance isn’t widely known. Whatever the reason, developing for [...]]]></description>
			<content:encoded><![CDATA[<p>(Download code <a href="http://www.bugfree.dk/blog/wp-content/uploads/2010/01/SharePointTemplatePatternRepositoryPattern.zip">here</a>. See related post on <a href="http://www.bugfree.dk/blog/2010/01/11/sharepoint-list-definition-using-the-template-pattern/">SharePoint list definition using the Template pattern</a>)</p>
<p>Maybe it’s that the SharePoint API is hard to use. Maybe it’s that coding against SharePoint is about making smaller additions here and there. Maybe it’s that the <a href="http://spg.codeplex.com">Patterns &amp; Practices SharePoint Guidance</a> isn’t widely known. Whatever the reason, developing for SharePoint requires equal attention to the separation of presentation, business, and data access code. Hence, starting with data access, we may want to create a repository and route queries through it (the SharePoint Guidance outlines a <a href="http://msdn.microsoft.com/en-us/library/ee413961.aspx">more sophisticated</a> implementation than the one below):</p>
<pre class="prettyprint lang-cs">[TestClass]
public class EmployeesRepositoryTest {
    private SPSite _siteCollection;
    private SPWeb _site;
    private EmployeesRepository _repository;

    private readonly Employee _duffyDuck = new Employee {
        Id = 1000, Name = &quot;Duffy Duck&quot;, HireDate = new DateTime(2009, 12, 1),
        Remarks = &quot;Looks like a duck, quacks like a duck, probably is a duck&quot;
    };
    private readonly Employee _porkyPig = new Employee {
        Id = 1001, Name = &quot;Porky Pig&quot;, HireDate = new DateTime(2010, 2, 1)
    };
    private readonly Employee _sylvesterTheCat = new Employee {
        Id = 1002, Name = &quot;Sylvester the Cat&quot;, HireDate = new DateTime(2010, 3, 1)
    };
    private readonly Employee _bugsBunny = new Employee {
        Id = 1100, Name = &quot;Bugs Bunny&quot;, HireDate = new DateTime(2010, 1, 1)
    };

    public void AddEmployees() {
        _repository.AddEmployee(_site, _duffyDuck);
        _repository.AddEmployee(_site, _porkyPig);
        _repository.AddEmployee(_site, _sylvesterTheCat);
    }

    public void ClearEmployees() {
        var definition = new EmployeesDefinition();
        var employees = _site.Lists[definition.ListName];
        while (employees.Items.Count &gt; 0)
            employees.Items.Delete(0);
    }

    [TestInitialize]
    public void Initialize() {
        _siteCollection = new SPSite(&quot;http://localhost&quot;);
        _site = _siteCollection.OpenWeb(&quot;/&quot;);
        _repository = new EmployeesRepository();
        ClearEmployees();
        AddEmployees();
    }

    [TestCleanup]
    public void Cleanup() {
        _site.Dispose();
        _siteCollection.Dispose();
    }

    [TestMethod]
    public void AddEmployee_should_add_valid_employee() {
        _repository.AddEmployee(_site, _bugsBunny);
        var e = _repository.GetEmployeeById(_site, _bugsBunny.Id);
        Assert.AreEqual(_bugsBunny.Id, e.Id);
        Assert.AreEqual(_bugsBunny.Name, e.Name);
        Assert.AreEqual(_bugsBunny.HireDate, e.HireDate);
        Assert.AreEqual(_bugsBunny.Remarks, e.Remarks);
    }

    [TestMethod]
    public void GetEmployeesHiredBetween_should_return_2010_hires() {
        var from = new DateTime(2010, 1, 1);
        var to = new DateTime(2010, 12, 31);
        var employees = _repository.GetEmployeesHiredBetween(_site, from, to);
        Assert.AreEqual(2, employees.Count);
        Assert.AreEqual(_porkyPig.Id, employees[0].Id);
        Assert.AreEqual(_sylvesterTheCat.Id, employees[1].Id);
    }
}</pre>
<p>In the words of Martin Fowler, here’s the <a href="http://martinfowler.com/eaaCatalog/repository.html">essence of the Repository pattern</a>:</p>
<blockquote>
<p>A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes. Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer.</p>
</blockquote>
<p>In SharePoint terms, business logic should query a repository which in turn queries a SharePoint list. Within the repository, the weakly typed items returned are then mapped to strongly typed <a href="http://en.wikipedia.org/wiki/Data_Transfer_Object">data transfer objects</a>, which are returned to the business layer.</p>
<p><img src="http://i.msdn.microsoft.com/Ee413961.a3b014d3-7677-4e99-886e-fd3432a8f914(en-us,MSDN.10).png" width="591" height="50" /></p>
<p>With this approach to data access comes a number of advantages: (1) duplicate data access code is eliminated. Only within the repository do we setup the query and transform the weakly typed <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splistitemcollection.aspx">SPListItemCollection</a> into strongly typed data transfer objects. (2) The list definition classes introduced in <a href="http://www.bugfree.dk/blog/2010/01/11/sharepoint-list-definition-using-the-template-pattern">SharePoint list definition using the Template pattern</a> may be used to construct CAML queries from strongly typed field names. Lastly, (3) accessing data through a repository makes it easier to mock the data access part of the application and to integration test that part.</p>
<p>The code below is a simple, yet usable, implementation of the Repository pattern. The idea is to have all repositories inherit from a common base class. Its purpose is to wrap the querying of a list and to <a href="http://www.bugfree.dk/blog/2009/07/22/basic-logging-guidelines">log what’s going on</a>. Because it’s a base class, it shouldn’t know how to transform the weakly typed result into strongly data transfer objects or which CRUD operations a particular repository supports:</p>
<pre class="prettyprint lang-cs">public abstract class ListRepository {
    protected ListDefinition Definition { get; set; }
    protected SPListItemCollection Result { get; set; }

    protected void Query(SPWeb site, string caml) {
        AssertValidSite(site);
        AssertValidCaml(caml);
        AssertListExistence(site);
        AssertListDefinitionSetBySubclass();

        var watch = new Stopwatch();
        var list = site.Lists[Definition.ListName];
        var query = new SPQuery {Query = caml};
        Debug.WriteLine(
            string.Format(&quot;About to run query against list '{0}': {1}&quot;, list, caml));
        watch.Start();
        Result = list.GetItems(query);
        watch.Stop();
        Debug.WriteLine(
            string.Format(&quot;Query against '{0}' returned {1} rows in {2} ms&quot;, 
                          list, Result.Count, watch.ElapsedMilliseconds));
    }

    protected void AssertListExistence(SPWeb site) {
        if (!ListDefinition.ListExists(site, Definition.ListName))
            throw new ArgumentException(
                string.Format(&quot;No '{0}' list on site '{1}'&quot;, Definition.ListName, site.Url));
    }

    protected void AssertListDefinitionSetBySubclass() {
        if (Definition == null)
            throw new NullReferenceException(
                string.Format(
                    &quot;Subclass must set Definition property prior querying '{0}' list&quot;, 
                    Definition.ListName));
    }

    protected void AssertValidCaml(string query) {
        if (string.IsNullOrEmpty(query))
            throw new NullReferenceException(&quot;Query must not be null or empty&quot;);
    }

    protected void AssertValidSite(SPWeb site) {
        if (site == null)
            throw new NullReferenceException(&quot;Site must not be null&quot;);
    }
}</pre>
<p>Each ListRepository connects to a corresponding ListDefinition, holding the name of the list to query and its strongly typed field names. It’s the responsibility of a concrete repository to set the Definition property prior to doing any querying. After running a query, the Result property holds the weakly typed result, which a concrete repository can then transform into data transfer objects to be passed to the business layer.</p>
<p>As an example, add to the concrete EmployeeRepository any CRUD method you see necessary to fulfill the business requirements:</p>
<pre class="prettyprint lang-cs">public class EmployeesRepository : ListRepository {
    public EmployeesRepository() {
        Definition = new EmployeesDefinition();
    }

    public void AddEmployee(SPWeb site, Employee e) {
        var list = site.Lists[Definition.ListName];
        var item = list.Items.Add();
        item[EmployeesDefinition.EmployeeId] = e.Id;
        item[EmployeesDefinition.Name] = e.Name;
        item[EmployeesDefinition.HireDate] = e.HireDate;
        item[EmployeesDefinition.Remarks] = e.Remarks;
        item.Update();
    }

    public Employee GetEmployeeById(SPWeb site, int id) {
        var caml =
            string.Format(@&quot;
                  &lt;Where&gt;
                    &lt;Eq&gt;
                      &lt;FieldRef Name=&quot;&quot;{0}&quot;&quot; /&gt;
                      &lt;Value Type=&quot;&quot;Integer&quot;&quot;&gt;{1}&lt;/Value&gt;
                    &lt;/Eq&gt;
                  &lt;/Where&gt;&quot;,
                EmployeesDefinition.EmployeeId, id);
        Query(site, caml);

        IList&lt;Employee&gt; employees = Map(Result);
        if (employees.Count == 0)
            throw new ArgumentException(string.Format(&quot;No employee with id = {0} exists&quot;, id));
        return employees[0];
    }

    public ReadOnlyCollection&lt;Employee&gt; GetEmployeesHiredBetween(SPWeb site, DateTime from, DateTime to) {
        var caml =
            string.Format(@&quot;
                  &lt;Where&gt;
                    &lt;And&gt;
                        &lt;Geq&gt;
                          &lt;FieldRef Name=&quot;&quot;{0}&quot;&quot; /&gt;
                          &lt;Value IncludeTimeValue=&quot;&quot;TRUE&quot;&quot; Type=&quot;&quot;DateTime&quot;&quot;&gt;{1}&lt;/Value&gt;
                        &lt;/Geq&gt;
                        &lt;Leq&gt;
                          &lt;FieldRef Name=&quot;&quot;{0}&quot;&quot; /&gt;
                          &lt;Value IncludeTimeValue=&quot;&quot;TRUE&quot;&quot; Type=&quot;&quot;DateTime&quot;&quot;&gt;{2}&lt;/Value&gt;
                        &lt;/Leq&gt;
                    &lt;/And&gt;
                  &lt;/Where&gt;&quot;,             
                EmployeesDefinition.HireDate, 
                SPUtility.CreateISO8601DateTimeFromSystemDateTime(from),
                SPUtility.CreateISO8601DateTimeFromSystemDateTime(to));
        Query(site, caml);
        return new ReadOnlyCollection&lt;Employee&gt;(Map(Result));
    }

    protected IList&lt;Employee&gt; Map(SPListItemCollection items) {
        var employees = new List&lt;Employee&gt;();
        foreach (SPItem item in items) {
            var e = new Employee {
                            Id = (int)item[EmployeesDefinition.EmployeeId],
                            Name = (string)item[EmployeesDefinition.Name],
                            HireDate = (DateTime)item[EmployeesDefinition.HireDate],
                            Remarks = (string)item[EmployeesDefinition.Remarks]
                        };
            employees.Add(e);
        }
        return employees;
    }
}</pre>
<p>Calling the GetEmployeeById or GetEmployeesHiredBetween methods, the caller is required to pass in an SPWeb instance pointing to the the site holding the list to query. Outside the SharePoint context, you have to manually create this instance, like with the integration tests above. But within the SharePoint context, callers are likely to just pass in SPContext.Current.Web.</p>
<p>The above repository implementation deliberately ignores any issue of caching. If you find the need for it, however, you can replace <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splist.getitems.aspx">SPList.GetItem</a> with <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.publishing.navigation.portalsitemapprovider.getcachedlistitemsbyquery.aspx">PortalSiteMapProvider.GetCachedListItemsByQuery</a>. The advantage of <a href="http://blogs.msdn.com/ecm/archive/2007/05/23/increased-performance-for-moss-apps-using-the-portalsitemapprovider.aspx">using the PortalSiteMapProvider</a> over Asp.Net caching of the result is that the provider takes care of invalidating cache entries when items are modified. The disadvantage is that the provider is part of the SharePoint publishing API, which isn’t part of WSS 3.0. In addition, it’s only available from code running within SharePoint, and likely requires cache settings to be tweaked.</p>
<p>Another, non-trivial, improvement would include the use of the <a href="http://martinfowler.com/eaaCatalog/unitOfWork.html">Unit of Work</a> pattern. A commonly used pattern in ORMs because it offers a way to “keep track of everything you do during a business transaction that can affect the database. When you&#8217;re done, it figures out everything that needs to be done to alter the database as a result of your work&quot;. Like with the <a href="http://msdn.microsoft.com/en-us/library/system.data.linq.datacontext.aspx">DataContext</a> class in LINQ to SQL or the <a href="http://msdn.microsoft.com/en-us/library/system.data.dataset.aspx">DataSet</a> class in ADO.NET, it could add transaction support to SharePoint lists.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2010/01/18/sharepoint-list-access-using-the-repository-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SharePoint list definition using the Template pattern</title>
		<link>http://www.bugfree.dk/blog/2010/01/11/sharepoint-list-definition-using-the-template-pattern/</link>
		<comments>http://www.bugfree.dk/blog/2010/01/11/sharepoint-list-definition-using-the-template-pattern/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 15:25:45 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Pattern]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1037</guid>
		<description><![CDATA[(Download code here. See related post on SharePoint list access using the Repository pattern) Books on SharePoint often show how to create lists from code by calling the SharePoint API from directly within a feature receiver. This receiver would then contain in-place string literals for column names, create the columns, update the default view, and [...]]]></description>
			<content:encoded><![CDATA[<p>(Download code <a href="http://www.bugfree.dk/blog/wp-content/uploads/2010/01/SharePointTemplatePatternRepositoryPattern.zip">here</a>. See related post on <a href="http://www.bugfree.dk/blog/2010/01/18/sharepoint-list-access-using-the-repository-pattern/">SharePoint list access using the Repository pattern</a>)</p>
<p>Books on SharePoint often show how to create lists from code by calling the SharePoint API from directly within a feature receiver. This receiver would then contain in-place string literals for column names, create the columns, update the default view, and so on. While such an approach provides for an nice demonstration of the SharePoint API, it tends to carry over into production code.</p>
<p>My take on feature receivers, however, is that they should contain the least possible amount of code. Staying true to object-orientation and separation of concerns, list definition and creation should instead consist of a common set of classes and methods to be called from the receiver:</p>
<pre class="prettyprint lang-cs">public override void FeatureActivated(SPFeatureReceiverProperties p) {
    using (var site = p.Feature.Parent as SPWeb) {
        var employees = new EmployeesDefinition();
        if (!ListDefinition.ListExists(site, employees.ListName)) 
            employees.CreateOnSite(site);            
    }
}</pre>
<p>The first area to improve on is that of string literal field names getting duplicated across the code base. String literals make it impossible for the compiler to enforce a consistent naming of columns. As column names are used in defining the list, in <a href="http://www.bugfree.dk/blog/2008/07/03/code-based-dynamic-caml-query-composition">forming CAML queries</a> against it, and in accessing the result, misspelled column names is a common source of runtime errors. The second area to improve on is that of duplication of code for doing common list operations, like checking for the existence of the list or removing its title column. Lastly, we want to get rid of duplicate control logic, i.e., verifying preconditions and calling the same series of methods with every list definition.</p>
<p>One approach to improving on these areas is to start by defining a base class for list definitions. The base class combines helper methods, working on lists, with the <a href="http://en.wikipedia.org/wiki/Template_method_pattern">Template pattern</a> for defining the common steps of list creation:</p>
<pre class="prettyprint lang-cs">public abstract class ListDefinition {
    public string ListName;
    public string ListDescription;
    protected SPList List;

    public void CreateOnSite(SPWeb site) {
        if (string.IsNullOrEmpty(ListName))
            throw new ArgumentException(&quot;Expected not null or not empty list name member&quot;);
        if (site == null) throw new NullReferenceException(&quot;Expected valid site&quot;);
        CreateList(site);
        if (List == null) throw new NullReferenceException(&quot;Expected list member not null&quot;);
        CreateFields(List);
        UpdateDefaultView(List);
        SetAdditionalProperties(List);
    }

    protected abstract void CreateList(SPWeb site);
    protected virtual void CreateFields(SPList l) {}
    protected virtual void UpdateDefaultView(SPList l) {}
    protected virtual void SetAdditionalProperties(SPList l) {}

    public static void HideAndMakeTitleFieldNotRequiredOnItemNewAndEditPage(SPList l) {
        var title = l.Fields.GetField(&quot;Title&quot;);
        title.Required = false;
        title.Hidden = true;
        title.Update();
    }

    public static bool ListExists(SPWeb site, string listName) {
        if (string.IsNullOrEmpty(listName))
            throw new ArgumentException(&quot;ListNameMustNotBeNullOrEmpty&quot;, listName);
        SPList list = null;
        try {
            list = site.Lists[listName];
        }
        catch (ArgumentException) {
            // list not found            
        }
        return list != null ? true : false;
    }
}</pre>
<p>At the core of the Template pattern is the template method. It defines the steps of an algorithm through a series of method calls. Each either abstract or virtual depending on if the step is mandatory or voluntary in the algorithm. Subclasses then specify the behavior of individual steps by implementing or overriding methods. In case of the ListDefinition class, CreateOnSite is our template method. It ensures that context, in the form of an <a href="http://msdn.microsoft.com/en-us/library/dd587308%28office.11%29.aspx">SPList</a> instance, is passed along to each step in the algorithm.</p>
<p>Each subclass defines the specific characteristics of a list. It defines constants for column names and their data types, the views and which column to index, and so on. This makes for a concise, easy to read, and consistent list definition:</p>
<pre class="prettyprint lang-cs">public class EmployeesDefinition : ListDefinition {
    public const string EmployeeId = &quot;EmployeeId&quot;;
    public const string Name = &quot;Name&quot;;
    public const string HireDate = &quot;HireDate&quot;;
    public const string Remarks = &quot;Remarks&quot;;

    public EmployeesDefinition() {
        ListName = &quot;AcmeEmployees&quot;;
        ListDescription = &quot;Employees at Acme Corp.&quot;;
    }

    protected override void CreateList(SPWeb site) {
        var guid = site.Lists.Add(ListName, ListDescription, SPListTemplateType.GenericList);
        List = site.Lists[guid];
    }

    protected override void CreateFields(SPList l) {
        l.Fields.Add(EmployeeId, SPFieldType.Integer, true);
        l.Fields.Add(Name, SPFieldType.Text, true);
        l.Fields.Add(HireDate, SPFieldType.DateTime, true);
        var remarks = (SPFieldMultiLineText) l.Fields[l.Fields.Add(Remarks, SPFieldType.Note, false)];
        remarks.RichText = true;
        remarks.RichTextMode = SPRichTextMode.FullHtml;
        remarks.Update();
        l.Update();
    }

    protected override void UpdateDefaultView(SPList l) {
        var v = l.DefaultView;
        v.ViewFields.Delete(&quot;LinkTitle&quot;);
        v.ViewFields.Add(EmployeeId);
        v.ViewFields.Add(Name);
        v.ViewFields.Add(HireDate);
        v.ViewFields.Add(Remarks);
        v.Update();
    }

    protected override void SetAdditionalProperties(SPList l) {
        HideAndMakeTitleFieldNotRequiredOnItemNewAndEditPage(l);
        l.Fields[HireDate].Indexed = true;
        l.Update();
    }
}</pre>
<p>Since the string literals have now become public constants, we get IntelliSense and compile-time checking referencing them. In addition, by defining common operations on the base class and using the Template pattern, we reduce the amount of code that would otherwise have to go into each definition. Finally, the base class asserts, on behalf of all subclasses, that the list name is set before attempting to create the list and that the SPList field is set after calling the CreateList method.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2010/01/11/sharepoint-list-definition-using-the-template-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Planning for 2010</title>
		<link>http://www.bugfree.dk/blog/2010/01/04/planning-for-2010/</link>
		<comments>http://www.bugfree.dk/blog/2010/01/04/planning-for-2010/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 00:54:21 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1038</guid>
		<description><![CDATA[In my previous post I looked at 2009 in hindsight. Consequently, in this one I look ahead at 2010 and what I want to accomplish professionally this coming year. I don’t plan on anything too esoteric. Instead, I want to consolidate my skills around building web applications with C#. My goals for the coming year [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://www.bugfree.dk/blog/2009/12/28/2009-in-retrospect/">previous</a> post I looked at 2009 in hindsight. Consequently, in this one I look ahead at 2010 and what I want to accomplish professionally this coming year. I don’t plan on anything too esoteric. Instead, I want to consolidate my skills around building web applications with C#.</p>
<p>My goals for the coming year are:</p>
<ul>
<li><strong>Focus more on architecture and design</strong>. Not in the <a href="http://www.joelonsoftware.com/articles/fog0000000018.html">architecture astronaut</a> connotation. But as in becoming more aware of how to build better software. I want to apply the <a href="http://blog.objectmentor.com/articles/2009/02/12/getting-a-solid-start">SOLID principles</a> more consciously and re-read classics such as <a href="http://en.wikipedia.org/wiki/Design_Patterns_%28book%29">Design Patterns: Elements of Reusable Object-Oriented Software</a> and <a href="http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420">Patterns of Enterprise Application Architecture</a>. </li>
<li><strong>Continue exploring LINQ</strong>. It’s a fascinating technology that’s going to get only more pervasive in years to come. Truly understanding LINQ is key to getting into the habit of applying a more functional and succinct style to my own code. To get started on this endeavor I’m going to read and apply <a href="http://www.amazon.com/LINQ-Action-Fabrice-Marguerie/dp/1933988169/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1262543982&amp;sr=8-1">LINQ in Action</a>. </li>
<li><strong>Learn</strong> <a href="http://en.wikipedia.org/wiki/ADO.NET_Entity_Framework">Entity Framework</a>. Using an object-relational mapper should be second-nature to any developer. In the past the light-weight LINQ to SQL has served me well. Still, I want to step up and learn how Entity Framework deals with the <a href="http://en.wikipedia.org/wiki/Object-relational_impedance_mismatch">impedance mismatch</a>. I want to write an application that uses Entity Framework. </li>
<li><strong>Become better at browser technologies</strong>. JavaScript and <a href="http://jquery.com">jQuery</a> are high on the list, but I want to improve on HTML and CSS as well. My goal isn’t to become an HTML or CSS Jedi. I simply want to have enough knowledge to avoid making rookie mistakes. The technologies all come together in jQuery, making <a href="http://www.amazon.com/Learning-jQuery-1-3-Jonathan-Chaffer/dp/1847196705/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1262569221&amp;sr=8-1">Learning jQuery</a> a good starting point. Besides, I want to use a tool like <a href="http://getfirebug.com">Firebug</a> to learn from others. </li>
<li><strong>Be on top of SharePoint 2010</strong>. SharePoint 2007 and 2010 is what I want to work with daily. That doesn’t imply me not keeping up to speed with the rest of .NET. Just that SharePoint will act as my gateway to other technologies. The great thing about SharePoint is that development is often split between working inside and outside SharePoint.</li>
<li><strong>Become more involved in higher-level development decisions</strong>. By the end of the day, developers don’t deliver software, they deliver value to stakeholders. Writing code is but a means to that end. I want to be involved in all steps from conception to completion. </li>
</ul>
<p>To me these points strike a good balance between technical and non-technical goals and between short and long term goals. However, by the end of the day, building great software is about being attentive to the entire stack and its surroundings.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2010/01/04/planning-for-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>2009 in retrospect</title>
		<link>http://www.bugfree.dk/blog/2009/12/28/2009-in-retrospect/</link>
		<comments>http://www.bugfree.dk/blog/2009/12/28/2009-in-retrospect/#comments</comments>
		<pubDate>Mon, 28 Dec 2009 11:26:49 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1036</guid>
		<description><![CDATA[As 2009 is drawing to a close, it’s time to look back and see what I’ve accomplished this past year. My professional goals for 2009 were to work on challenging software development tasks, preferably on larger projects. I wanted to continue to grow my skills working with .Net in general and SharePoint in particular. In [...]]]></description>
			<content:encoded><![CDATA[<p>As 2009 is drawing to a close, it’s time to look back and see what I’ve accomplished this past year. My professional goals for 2009 were to work on challenging software development tasks, preferably on larger projects. I wanted to continue to grow my skills working with .Net in general and SharePoint in particular. In addition, I wanted to be more involved with higher-level development decisions, such as requirements gathering and solution design.</p>
<p>So how did the year go?</p>
<ul>
<li><strong>Changed jobs to one that gravitates more around larger projects</strong>. The rationale being that larger projects come with larger engineering challenges. I spend six months on an Asp.Net project followed by three on a SharePoint project. For various reasons, I wasn’t as involved in higher-level development decisions as I would’ve liked to. </li>
<li><strong>Did two presentations</strong>. One on <a href="http://www.bugfree.dk/blog/2009/06/19/basic-unit-testing-guidelines">Unit testing and mocking</a> for the Asp.Net project that I was working on at the time. The other presentation was on <a href="http://www.bugfree.dk/blog/2009/11/26/parallel-page-processing-with-asp-net">Parallel page rendering with Asp.Net</a> and SharePoint for my current project. None involving rocket science, but I find so few are familiar with the techniques. </li>
<li><strong>Made my way through three certifications</strong>. The <a href="http://www.microsoft.com/learning/en/us/exam.aspx?ID=70-536">70-536</a>: MS .NET Framework, Application Development Foundation, <a href="http://www.microsoft.com/learning/en/us/exam.aspx?ID=70-562">70-562</a>: MS .NET Framework 3.5, ASP.NET Application Development, and <a href="http://www.prince2.com">Prince2 Foundation</a>. I’ve mixed feelings with regard to certifications, though. Certainly, I learned valuable lessons studying for each one. Yet, given the same amount of time, I’m inclined to think I would’ve learned more studying books, blogs, listening to various podcasts, and writing. </li>
<li><strong>Attended the </strong><a href="http://www.bugfree.dk/blog/2009/10/12/jaoo-2009-conference">Jaoo conference</a><strong> on software engineering</strong>. It was my first time ever attending a conference and it sure was enlightening. I intentionally went for a conference not tied to a specific vendor because I felt I’d learn more that way. My issue with Microsoft conferences like Tech-Ed or PDC is their focus on the latest technology buzz. Buzz that quickly becomes obsolete or is already heavily exposed on the web. Not to mention that most sessions are available online afterward. </li>
<li><strong>Learned functional programming</strong>. My focus on new technology has mostly been on various aspects of functional programming. A subject that’s interested me for years, but one that’s only recently started to permeate C#, my language of choice. I learned a great deal about F# when I <a href="http://www.bugfree.dk/blog/2009/03/06/generating-2d-random-fractal-terrains-with-f">generated fractal terrains</a> and about XSL when I had to <a href="http://www.bugfree.dk/blog/2009/06/13/jumping-through-loops-with-xsl">jump through functional loops</a> and about functional programming in general. </li>
<li><strong>Wrote 16 blog posts</strong> (25 pages, 10,000 words). Compared to previous years it’s a record. Naturally, not all posts were equally good. Nevertheless I enjoyed learning about the subjects and feel they helped advance my writing skills. The posts on <a href="http://www.bugfree.dk/blog/2009/06/19/basic-unit-testing-guidelines/">Basic unit testing guidelines</a> and <a href="http://www.bugfree.dk/blog/2009/08/15/why-not-to-comment-code">Why not to comment code</a> did manage to gain traction on Reddit, though. </li>
</ul>
<p>All things considered, I’m pleased with 2009. The only thing I regret is not being more involved in higher-level development decisions. I like coding, but it’s a means to an end. Being involved with a task from start to finish is what ignites my fire. I must push harder on that in 2010.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2009/12/28/2009-in-retrospect/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Printing iframe content using JavaScript</title>
		<link>http://www.bugfree.dk/blog/2009/12/17/printing-iframe-content-using-javascript/</link>
		<comments>http://www.bugfree.dk/blog/2009/12/17/printing-iframe-content-using-javascript/#comments</comments>
		<pubDate>Thu, 17 Dec 2009 21:50:41 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Html]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=1005</guid>
		<description><![CDATA[JavaScript is on top of the list of things I’d like to become better at. So I was quite happy when assigned a JavaScript-related defect in an application at work. Apparently, there was a bug in the JavaScript routine used for printing only the content of an iframe on a page. Rather than printing only [...]]]></description>
			<content:encoded><![CDATA[<p>JavaScript is on top of the list of things I’d like to become better at. So I was quite happy when assigned a JavaScript-related defect in an application at work. Apparently, there was a bug in the JavaScript routine used for printing only the content of an iframe on a page. Rather than printing only the iframe’s content, it printed the page hosting the iframe, cropping parts of the iframe’s content.</p>
<p>I started out confident that printing would be easy to fix. But after Googling and playing around with JavaScript for a while, frustration, fueled by the number of non-working hits I’d stumbled on, started to grow on me. Suppose you start out with an HTML document hosting an iframe and a few lines of JavaScript.</p>
<pre class="prettyprint lang-html">&lt;html&gt;
    &lt;head&gt;
        &lt;title&gt;IFrame printing example&lt;/title&gt;
        &lt;script type=&quot;text/javascript&quot;&gt;
            function myPrint() {
                var browser = navigator.appName;
                if (browser == &quot;Microsoft Internet Explorer&quot;) {
                    window.frames[&quot;frame&quot;].focus();
                    window.frames.print();
                }
                else if (browser == &quot;Netscape&quot;)
                    alert(&quot;Printing not supported in Firefox&quot;);
            }
        &lt;/script&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;iframe id=&quot;frame&quot; name=&quot;frame&quot; width=&quot;100&quot;
            height=&quot;100&quot; src=&quot;http://google.com&quot;&gt;
        &lt;/iframe&gt;
        &lt;a href=&quot;#&quot; onclick=&quot;javascript:myPrint();&quot;&gt;Print&lt;/a&gt;
    &lt;/body&gt;
&lt;/html&gt;</pre>
<p>A number of issues arise when printing the iframe. First you need to consider if you’re always hosting the main document on the same domain as the iframe’s source. If so, printing only the iframe with Internet Explorer works like a charm. If, on the other hand, the main document and the iframe’s source reside on different domains, it triggers Internet Explorer to displays a bar across the top of the window.</p>
<p><img src="http://www.bugfree.dk/blog/wp-content/uploads/2009/12/allow-blocked-content-browser-bar.png" /></p>
<p>Now, to print the iframe’s content, you must allow blocked content. Only then can JavaScript access the iframe’s object model. But at the same time, you make yourself vulnerable to <a href="http://en.wikipedia.org/wiki/Cross-site_scripting">cross-site scripting attacks</a>.</p>
<p>As far as Firefox support goes, you can issue the same API calls as for Internet Explorer. But Firefox will always print the main page, including only the visible parts of the iframe. To my knowledge there’s no way to make Firefox print the iframe’s content as seamlessly as Internet Explorer. One workaround, though, would be to open a new window, grab a reference to the iframe element, and move its contents to the new window before printing it. For cross-domain content, however, Firefox responds with a “permission denied” error when accessing the iframe element. And there’s no option to allow blocked content. Another workaround may therefore be to use Ajax to retrieve the source of the iframe for any domain and insert it into the new window. That, however, wouldn’t work in my case since the iframe may contain a form that the user may have started filling out before hitting print.</p>
<p>As a last resort, I considered writing a proxy to retrieve cross-domain hosted content. This would make Internet Explorer never display the bar and allow Firefox to always open a new window with the iframe’s content loaded, even if the user started filling out a form first. But this approach sort of defies the purpose of the browser bar and the permission denied error. Unless you absolutely trust your iframe’s source, you’re exposing your users without their consent.</p>
<p>In the end I went with the simplest and most secure solution of not supporting printing at all.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2009/12/17/printing-iframe-content-using-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Parallel page processing with Asp.Net</title>
		<link>http://www.bugfree.dk/blog/2009/11/26/parallel-page-processing-with-asp-net/</link>
		<comments>http://www.bugfree.dk/blog/2009/11/26/parallel-page-processing-with-asp-net/#comments</comments>
		<pubDate>Thu, 26 Nov 2009 09:02:00 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Asp.Net]]></category>
		<category><![CDATA[Presentation]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=993</guid>
		<description><![CDATA[(This post grew out of a presentation I did on the subject. Turn to the slides for more details, including code.) With Asp.Net, by default a page is rendered synchronously, one control at a time. The thread rendering the page comes from the thread pool within the world wide web worker process (w3wp.exe) and is [...]]]></description>
			<content:encoded><![CDATA[<p>(This post grew out of a presentation I did on the subject. Turn to the <a href="http://www.bugfree.dk/blog/wp-content/uploads/2009/11/Parallel page processing with Asp.Net.pdf">slides</a> for more details, including code.)</p>
<p>With Asp.Net, by default a page is rendered synchronously, one control at a time. The thread rendering the page comes from the thread pool within the world wide web worker process (w3wp.exe) and is assigned to the request when it comes in on the web server. Only when the page has fully rendered can the thread go back in the pool waiting for the next request.</p>
<p>Processing a complex page using only one thread, however, may cause the page to render slowly. The page may hold controls that require calls to web services, databases, or other external resources for it to render. Whenever the worker thread encounters such a control, it goes idle waiting for data to come back from the external resource. Only when data is received can the worker thread resume processing.</p>
<p>One way to speed up page processing would be for the page or control to explicitly make use of threads. Depending on the situation, this may be a cumbersome task that requires a significant amount of boiler-plate code. A simpler approach might be to turn to the Asp.Net 2.0 feature for asynchronous page processing. At its core is an extension to the page or control lifecycle.</p>
<p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
<img src="http://www.bugfree.dk/blog/wp-content/uploads/2009/11/Comparable-page-lifecycles.gif" /><br/></p>
<p>Except for the <a href="http://msdn.microsoft.com/en-us/library/system.web.begineventhandler.aspx">Begin</a> and <a href="http://msdn.microsoft.com/en-us/library/system.web.endeventhandler.aspx">End</a> events, the flow is the same in both models. But while the synchronous model executes all code on a single thread, the asynchronous model makes implicit use of multiple worker threads to speed up page processing. With multiple threads, some threads still go idle waiting for input, but at least the main worker thread continues to work its way through the controls.</p>
<p>In the asynchronous model, we hook into the Begin and End handlers in one of the events preceding the call to Begin. Following PreRender, Asp.Net will then execute our Begin handler, where we call out to some method that carries out the long-running task. When that method exists the End handler is called and processing carries on as in the synchronous model.</p>
<p>To illustrate the flow and timing of the asynchronous model (turn to the slides for the complete code sample), suppose we add five controls to a page. Each control takes five seconds to render so using the synchronous model the page would take 25 seconds to render. Using the asynchronous model, and writing out trace information about which thread each method executes on, here&#8217;s what happens:</p>
<pre>1: Page_Load: 10            9: DoWork: 8
2: Page_Load: 10           10: DoWork: 11
3: Page_Load: 10           11: Render: 11 15:16:13 15:16:18
4: Page_Load: 10           12: Render: 11 15:16:13 15:16:18
5: Page_Load: 10           13: Render: 11 15:16:13 15:16:18
6: DoWork: 4               14: Render: 11 15:16:13 15:16:18
7: DoWork: 10              15: Render: 11 15:16:13 15:16:19 
8: DoWork: 9</pre>
<p>The user control&#8217;s Page_Load and the code making up the Begin handler executes on the main worker thread. But the method carrying out the long-running task, and the code for the End handler, executes in parallel on different worker threads. Finally, after End is called, another worker thread takes over and executes the remaining parts of the control. Now page rendering has decreased from 25 to about five seconds.</p>
<p>All in all, little effort is required to make more efficient, and implicit, use of the thread pool, thereby decreasing the time required processing a page. Asynchronous page processing should be used judiciously, though. Optimizing away a bottleneck in the processing of a page may well lead to bottlenecks appearing elsewhere, e.g., the number of simultaneous calls made to a web service may be too much for it to handle.</p>
<p>For more details and examples, turn to <a href="http://www.wintellect.com/cs/blogs/jprosise/default.aspx">Jeff Prosise</a>&#8216;s article on <a href="http://msdn.microsoft.com/en-us/magazine/cc163725.aspx">Asynchronous Pages in Asp.Net 2.0</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2009/11/26/parallel-page-processing-with-asp-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting organized with Emacs Org-mode</title>
		<link>http://www.bugfree.dk/blog/2009/11/05/getting-organized-with-emacs-org-mode/</link>
		<comments>http://www.bugfree.dk/blog/2009/11/05/getting-organized-with-emacs-org-mode/#comments</comments>
		<pubDate>Thu, 05 Nov 2009 21:42:02 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Emacs]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Tool]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=694</guid>
		<description><![CDATA[It&#8217;s been four months and 350 clocked work-hours since I started using Org-mode for Emacs. I use Org-mode, mixed with some of the Pomodoro principles, to maintain my task lists at work and home. In a nutshell Org-mode is a plug-in for Emacs that makes taking notes, maintaining lists, clocking time, and many other tasks [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been four months and 350 clocked work-hours since I started using <a href="http://orgmode.org">Org-mode</a> for <a href="http://www.gnu.org/software/emacs/">Emacs</a>. I use Org-mode, mixed with some of the <a href="http://www.pomodorotechnique.com">Pomodoro principles</a>, to maintain my task lists at work and home.</p>
<p>In a nutshell Org-mode is a plug-in for Emacs that makes taking notes, maintaining lists, clocking time, and many other tasks more straightforward. The mode works by adding features on top of Emacs for editing plain text files. Features that enrich the interaction with the underlying text buffer by parsing and adding (meta-)information to it.</p>
<p>With Org-mode you group items into a hierarchical structure. A path to the item to work on is then formed by unfolding items in a way analogous to how you navigate the file system with Explorer.</p>
<p><img alt="" src="http://www.bugfree.dk/blog/wp-content/uploads/2009/11/Org-mode-example1.png" /></p>
<p>To efficiently work with items, Org-mode supports moving items around the hierarchy. Items may also be tagged (buy, work, phone, etc.) or associated with a state (done, waiting, started, etc.). Additional meta-information may include a deadline, an estimate, or time spent working on a task. The clocking of time is accomplished by Org-mode adding a timestamp to the item. On completion, another timestamp and the elapsed time is calculated and added.</p>
<p>Below is an example of an expanded and a collapsed item containing clocked times and estimates.</p>
<p><img alt="" src="http://www.bugfree.dk/blog/wp-content/uploads/2009/11/Org-mode-example2.png" /></p>
<p>With a few keystrokes, Org-mode is able to correlate estimates with time spent on an item-by-item basis. This truly short-circuits the estimation feedback cycle. Imagine doing this on a file containing a large hierarchy of items and the transparency it brings.</p>
<p><img alt="" src="http://www.bugfree.dk/blog/wp-content/uploads/2009/11/Org-mode-example3.png" /></p>
<p>If you want to keep track of billable hours, it may make sense to clock all your time using Org-mode and generate timesheets from the clocking information. Especially since the billing context is automatically provided by the item storing the timestamp, and since you&#8217;re free to organize the file in any way you see fit. Few other tools manage to compete with the flexibility of a plain text buffer.</p>
<p>This post only scratches the surface of Org-mode. To get a sense of the possibilities, the <a href="http://orgmode.org/org.pdf">manual</a> amounts to 184 pages. However, for a quick introduction I encourage you to watch the <a href="http://orgmode.org/GoogleTech.html">Google Tech Talk on Org-mode</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2009/11/05/getting-organized-with-emacs-org-mode/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Jaoo 2009 conference</title>
		<link>http://www.bugfree.dk/blog/2009/10/12/jaoo-2009-conference/</link>
		<comments>http://www.bugfree.dk/blog/2009/10/12/jaoo-2009-conference/#comments</comments>
		<pubDate>Mon, 12 Oct 2009 14:47:46 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Conference]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=670</guid>
		<description><![CDATA[(My notes from the conference is available here.) From Oct 5 to Oct 7, I was fortunate enough to attend the Jaoo 2009 conference on software engineering in Aarhus. It was a great conference with three days of insightful talks. The talks I attended were: Monday Keynote: Scaling Up Agility: The Architected Agile Approach/Barry Boehm [...]]]></description>
			<content:encoded><![CDATA[<p>(My notes from the conference is available <a href="http://www.bugfree.dk/blog/notes/jaoo-2009/">here</a>.)</p>
<p>From Oct 5 to Oct 7, I was fortunate enough to attend the <a href="http://jaoo.dk/aarhus-2009">Jaoo 2009 conference</a> on software engineering in Aarhus. It was a great conference with three days of insightful talks. The talks I attended were:
</p>
<p>Monday
</p>
<ul>
<li><a href="http://jaoo.dk/aarhus-2009/presentation/Scaling+Up+Agility%3A+The+Architected+Agile+Approach">Keynote: Scaling Up Agility: The Architected Agile Approach/Barry Boehm</a> (<a href="http://jaoo.dk/aarhus-2009/file?path=/jaoo-aarhus-2009/slides/BarryBoehm_ScalingUpAgilityTheArchitectedAgileApproach.pdf">slides</a>)
</li>
<li><a href="http://jaoo.dk/aarhus-2009/presentation/Working+Effectively+with+Legacy+Code+2">Working Effectively with Legacy Code 2/Michael Feathers</a> (<a href="http://jaoo.dk/aarhus-2009/file?path=/jaoo-aarhus-2009/slides/MichaelFeathers_WorkingEffectivelyWithLegacyCode2.pdf">slides</a>)
</li>
<li><a href="http://jaoo.dk/aarhus-2009/presentation/Evolving+the+Key%2FValue+Programming+Model+to+a+Higher+Level">Evolving the Key/Value Programming Model to a Higher Level/Billy Newport</a> (<a href="http://jaoo.dk/aarhus-2009/file?path=/jaoo-aarhus-2009/slides/BillyNewport_EvolvingTheKeyValueProgrammingModelToAHigherLevel.pdf">slides</a>)
</li>
<li><a href="http://jaoo.dk/aarhus-2009/presentation/Techniques+That+Still+Work+no+Matter+How+Hard+We+Try+to+Forget+Them">Techniques That Still Work no Matter How Hard We Try to Forget Them/Keith Braithwaite</a> (<a href="http://jaoo.dk/aarhus-2009/file?path=/jaoo-aarhus-2009/slides/MichaelFeathers_CleanCodeIIIFunctions.pdf">slides</a>)
</li>
<li><a href="http://jaoo.dk/aarhus-2009/presentation/Making+use+of+Patterns">Making use of Patterns/Martin Fowler</a>
		</li>
<li><a href="http://jaoo.dk/aarhus-2009/presentation/xUnit+Test+Patterns+-+Refactoring+Test+Code+to+Improve+ROI">xUnit Test Patterns &#8211; Refactoring Test Code to Improve ROI/Gerard Meszaros</a> (<a href="http://jaoo.dk/aarhus-2009/file?path=/jaoo-aarhus-2009/slides/GerardMeszaros_XUnitTestPatternsRefactoringTestCodeToImproveROI.pdf">slides</a>)
</li>
</ul>
<p>Tuesday
</p>
<ul>
<li><a href="http://jaoo.dk/aarhus-2009/presentation/Classes%2C+Jim%2C+But+Not+as+We+Know+Them">Keynote: Classes, Jim, But Not as We Know Them/Simon Peyton-Jones</a> (<a href="http://jaoo.dk/aarhus-2009/file?path=/jaoo-aarhus-2009/slides/SimonPeyton-Jones_ClassesJimButNotAsWeKnowThem.pdf">slides</a>)
</li>
<li><a href="http://jaoo.dk/aarhus-2009/presentation/Agile+Modeling+and+Documentation+%22Best%22+Practices">Agile Modeling and Documentation &#8220;Best&#8221; Practices/Scott Ambler</a> (<a href="http://jaoo.dk/aarhus-2009/file?path=/jaoo-aarhus-2009/slides/ScottAmbler_AgileModelingAndDocumentationBestPractices.pdf">slides</a>)
</li>
<li><a href="http://jaoo.dk/aarhus-2009/presentation/Actors%2C+and+the+Forgotten+Art+of+Modeling+Concurrent+Systems">Actors, and the Forgotten Art of Modeling Concurrent Systems/Dave Thomas, Kresten Krab Thorup</a> (<a href="http://jaoo.dk/aarhus-2009/file?path=/jaoo-aarhus-2009/slides/DaveThomas_and_KrestenKrabThorup_ActorsAndTheForgottenArtOfModelingConcurrentSystems.pdf">slides</a>)
</li>
<li><a href="http://jaoo.dk/aarhus-2009/presentation/Buy+it%2C+Build+it%2C+Download+It%2C+or+Browse+It%3F+Achieving+Effectiveness+with+Enterprise+Applications">Buy it, Build it, Download It, or Browse It? Achieving Effectiveness with Enterprise Applications/Michael T. Nygard</a> (<a href="http://jaoo.dk/aarhus-2009/file?path=/jaoo-aarhus-2009/slides/MichaelT.Nygard_BuyItBuildItDownloadItOrBrowseItAchievingEffectivenessWithEnterpriseApplications.pdf">slides</a>)
</li>
<li><a href="http://jaoo.dk/aarhus-2009/presentation/Hydras+and+Hypermedia">Hydras and Hypermedia/Ian Robinson</a> (<a href="http://jaoo.dk/aarhus-2009/file?path=/jaoo-aarhus-2009/slides/IanRobinson_HydrasAndHypermedia.pdf">slides</a>)<a href="http://jaoo.dk/aarhus-2009/presentation/Maximum+Value%2C+Maximum+Speed+through+Lean+Thinking+-+How+Business+and+IT+can+Collaborate"><br />
			</a></li>
<li><a href="http://jaoo.dk/aarhus-2009/presentation/Maximum+Value%2C+Maximum+Speed+through+Lean+Thinking+-+How+Business+and+IT+can+Collaborate">Maximum Value, Maximum Speed through Lean Thinking &#8211; How Business and IT can Collaborate/Dave Thomas</a>
</li>
</ul>
<p>Wednesday
</p>
<ul>
<li><a href="http://jaoo.dk/aarhus-2009/presentation/C%2B%2B%2C+Java+and+.NET+-+Lessons+Learned+from+the+Internet+Age%2C+and+What+it+Means+for+the+Cloud+and+Emerging+Languages">Keynote: C++, Java and .NET &#8211; Lessons Learned from the Internet Age, and What it Means for the Cloud and Emerging Languages/Cameron Purdy</a> (<a href="http://jaoo.dk/aarhus-2009/file?path=/jaoo-aarhus-2009/slides/CameronPurdy_CJavaAndNETLessonsLearnedFromTheInternetAgeAndWhatItMeansForTheCloudAndEmergingLanguages.pdf">slides</a>)
</li>
<li><a href="http://jaoo.dk/aarhus-2009/presentation/Guiding+Your+Personal+Life+--+%22Plan-Driven%22+or+%22Agile%22+--">Guiding Your Personal Life &#8212; &#8220;Plan-Driven&#8221; or &#8220;Agile&#8221;/Linda Rising</a> (<a href="http://jaoo.dk/aarhus-2009/file?path=/jaoo-aarhus-2009/slides/LindaRising_GuidingYourPersonalLifePlanDrivenOrAgile.pdf">slides</a>)
</li>
<li><a href="http://jaoo.dk/aarhus-2009/presentation/Object+Relational+Mapping+%2B%3D+2%3A+More+than+just+data+%3C-%3E+object">Object Relational Mapping += 2: More than just data &lt;-&gt; object/Oren Eini</a>
		</li>
<li><a href="http://jaoo.dk/aarhus-2009/presentation/Deliberate+Practice+in+Software+Development">Deliberate Practice in Software Development/Mary Poppendieck</a> (<a href="http://jaoo.dk/aarhus-2009/file?path=/jaoo-aarhus-2009/slides/MaryPoppendieck_DeliberatePracticeInSoftwareDevelopment.pdf">slides</a>)
</li>
<li><a href="http://jaoo.dk/aarhus-2009/presentation/Umbraco%2C+An+Open+Source+Web+CMS+that+Devs+Will+Like...+Really%3F">Umbraco: An Open Source Web CMS that Devs Will Like &#8230; Really?</a> (<a href="http://jaoo.dk/aarhus-2009/file?path=/jaoo-aarhus-2009/slides/NielsHartvig_UmbracoAnOpenSourceWebCMSThatDevsWillLikeReally.pdf">slides</a>)
</li>
<li><a href="http://jaoo.dk/aarhus-2009/presentation/Delivering+Quantified+Stakeholder+Values+with+Agile+-+A+Case+study+from+Bring">Delivering Quantified Stakeholder Values with Agile &#8211; A Case study from Bring/Kai Gilb</a> (<a href="http://jaoo.dk/aarhus-2009/file?path=/jaoo-aarhus-2009/slides/KaiGilb_DeliveringQuantifiedStakeholderValuesWithAgileACaseStudyFromBring.pdf">slides</a>)
</li>
</ul>
<p>As a supplement to the official homepage, the <a href="http://twitter.com/jaoo">Twitter feed</a> provided a great source of information for attendees to learn about the presentations and reactions. Not being on Twitter meant missing out on half the conference.</p>
<p>For other reactions, listen to (in Danish) <a href="http://danielfrost.dk">Daniel Frost</a> and <a href="http://kodehoved.dk">Brian Rasmussen</a> discussing day <a href="http://danielfrost.dk/post/Frostse28099-Podcast-Show-e2809cspeciteal-editione2809d-e28093-JAOO-dag-1.aspx">one</a> and <a href="http://danielfrost.dk/post/Frostse28099-Podcast-Show-e2809cspecial-editione2809d-e28093-JAOO-dag-2.aspx">two</a>. On day <a href="http://danielfrost.dk/post/Frostse28099-Podcast-Show-e2809cspecial-editione2809d-e28093-Mads-Torgersen.aspx">three</a> Daniel interviewed Mads Torgersen of the C# core team.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2009/10/12/jaoo-2009-conference/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why not to comment code</title>
		<link>http://www.bugfree.dk/blog/2009/08/15/why-not-to-comment-code/</link>
		<comments>http://www.bugfree.dk/blog/2009/08/15/why-not-to-comment-code/#comments</comments>
		<pubDate>Sat, 15 Aug 2009 19:55:24 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Quality]]></category>
		<category><![CDATA[Refactoring]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=535</guid>
		<description><![CDATA[Update, Aug 18, 2009: I&#8217;m amazed at how much attention this post has received. More than 200 comments on Reddit. I was just listening to the Why comments are evil episode of Deep Fried Bytes. The views put forward by the guest, Corey Haines, deeply resonate with me because I believe they&#8217;re what every developer [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update, Aug 18, 2009</strong>: I&#8217;m amazed at how much <a href="http://www.reddit.com/r/programming/comments/9b4ct/why_not_to_comment_code">attention</a> this post has received. More than 200 comments on Reddit.
</p>
<p>I was just listening to the <a href="http://deepfriedbytes.com/podcast/episode-35-why-comments-are-evil-and-pair-programming-with-corey-haines">Why comments are evil</a> episode of <a href="http://deepfriedbytes.com">Deep Fried Bytes</a>. The views put forward by the guest, <a href="http://www.coreyhaines.com/">Corey Haines</a>, deeply resonate with me because I believe they&#8217;re what every developer should strive for. I&#8217;m not advocating that code should be entirely free of comments, but rather that most comments do more harm than good.
</p>
<p>Below I&#8217;ve listed the main points of view.
</p>
<ul>
<li>It&#8217;s important to differentiate between code comments and API documentation. For API documentation, don&#8217;t auto-generate. Especially don&#8217;t go with tools like <a href="http://submain.com/products/ghostdoc.aspx">GhostDoc</a>. Take the time to document properly. Otherwise, you&#8217;re more likely to confuse the developer trying to make sense of your code.
</li>
<li>Stop focusing on having the computer understand you and start focusing on the person that comes after you, e.g., while there&#8217;s some overhead to method calls, unless the profiler tells you otherwise, don&#8217;t hesitate to break down a method into as many smaller methods as it takes to make it more approachable.
</li>
<li>Every time you&#8217;re tempted to comment, take the time to think if you can make the code tell its own story, e.g., instead of some branching condition, extract the condition into a method to emphasize the story of why over how.
</li>
<li>Developers comment to explain a confusing part of their code rather than take the time to <a href="http://en.wikipedia.org/wiki/Refactoring">refactor</a> it by extracting a method or naming a variable properly. Inevitably the code gets modified and the comment rots.
</li>
<li>Parts of a method may be complicated so a comment is added. Saying part of a method is complicated is in itself a sign that it&#8217;s doing too much.
</li>
<li>The prevailing culture among developers is to focus on what it takes to get code working. It&#8217;s a battle of short-term vs. long-term maintainability and short-term almost always comes out as the winner. Writing code, ask yourself if you&#8217;re able to immediately understand the code a month from now.
</li>
</ul>
<p>The opinions put forward in the episode aren&#8217;t new. Still, I find them well worth iterating because as developers we tend to not pay enough attention to them. We tend to focus too little on good <a href="http://manifesto.softwarecraftsmanship.org/">software craftsmanship</a>.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2009/08/15/why-not-to-comment-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Becoming aware of and minimizing distractions</title>
		<link>http://www.bugfree.dk/blog/2009/07/27/becoming-aware-of-and-minimizing-distractions/</link>
		<comments>http://www.bugfree.dk/blog/2009/07/27/becoming-aware-of-and-minimizing-distractions/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 20:14:31 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Tool]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=295</guid>
		<description><![CDATA[Spending a great deal of time in front of my computer, I often get carried away by instant messaging, mail, RSS, Twitter, Facebook, etc. For the most part, these activities aren&#8217;t the reason I turned on the computer. Nevertheless they end up being where a lot of time is spent. Like with any habit, every [...]]]></description>
			<content:encoded><![CDATA[<p>Spending a great deal of time in front of my computer, I often get carried away by instant messaging, mail, RSS, Twitter, Facebook, etc. For the most part, these activities aren&#8217;t the reason I turned on the computer. Nevertheless they end up being where a lot of time is spent.
</p>
<p>Like with any habit, every so often you should take the time to review it. I find <a href="http://timesnapper.com/">TimeSnapper</a> (the free edition) to be an invaluable tool for reviewing computer habits. It captures an image of the desktop every few seconds and is able to create a movie from the images. That way, a partial <a href="http://en.wikipedia.org/wiki/Lifelog">life log</a> (mine is currently 393 days) is automatically created to help you remember what you did yesterday and the day before.
</p>
<p>There&#8217;s nothing like reviewing a few of weeks of captured images to make habits stand out. I found that I&#8217;ve a tendency to re-visit the same maybe ten sites all too often. I also have difficulty single-tasking. Listening to a podcast or watching a movie, I&#8217;m often browsing the web instead of paying attention to the podcast or skipping it altogether. I may even have several media players launched at once, although only one playing.
</p>
<p>Most of my distractions can be attributed to me always being online. I need Internet access for work, so turning it off altogether isn&#8217;t an alternative. So, not unlike <a href="http://www.paulgraham.com">Paul Graham</a>, on several occasions, I&#8217;ve made myself adhere to a set of rules for using the Internet. And every time they&#8217;ve worked &#8212; for a short while.
</p>
<p>In <a href="http://www.paulgraham.com/distraction.html">Disconnecting Distraction</a>, Paul takes these rules one step further and argues that using two computers may be a better solution: one computer with Internet access and one without for doing real work. Ideally, the computers should be placed some distance apart to make you psychically get up to go on the Internet.
</p>
<p>For a week I&#8217;ve given the two-computer approach a try. It was hard initially, but I&#8217;ve come to appreciate it. Forming permanent habits takes time. Thus, I&#8217;ll continue the experiment for a couple of weeks. Perhaps in time I&#8217;ll even learn to turn off instant messaging and only do mail once or twice a day. Or I may end up spending most of the time in front of the connected computer.
</p>
<p>Then again, there&#8217;s more to life than work.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2009/07/27/becoming-aware-of-and-minimizing-distractions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Basic logging guidelines</title>
		<link>http://www.bugfree.dk/blog/2009/07/22/basic-logging-guidelines/</link>
		<comments>http://www.bugfree.dk/blog/2009/07/22/basic-logging-guidelines/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 11:28:22 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Quality]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=188</guid>
		<description><![CDATA[Next to unit testing I believe in logging to improve the quality of an application. Instrumenting code with logging (or tracing for that matter) should be an integral part of writing production code. Yet, I&#8217;ve often found it not to be the case or that what got logged only made sense to the developer who [...]]]></description>
			<content:encoded><![CDATA[<p>Next to <a href="http://www.bugfree.dk/blog/2009/06/19/basic-unit-testing-guidelines/">unit testing</a> I believe in logging to improve the quality of an application. Instrumenting code with <a href="http://en.wikipedia.org/wiki/Data_logging">logging</a> (or <a href="http://en.wikipedia.org/wiki/Tracing_(software)">tracing</a> for that matter) should be an integral part of writing production code. Yet, I&#8217;ve often found it not to be the case or that what got logged only made sense to the developer who wrote the entry.
</p>
<p>Not logging implies that debugging the application outside the development environment is largely based on guesswork. That’s interesting given that most applications spend the majority of their life running outside the development environment.
</p>
<h4>Life in the sandbox<br />
</h4>
<p>I suspect the absence or low quality of log statements can be, at least partially, explained by developers not finding them useful during development. The debugger available there is generally inferior to the print-lining approach of logging. That said, I&#8217;d argue that many developers don&#8217;t concern themselves enough with how their code behaves in a production environment. Rather than investing a small amount of time in adding log statements up-front, their focus is solely on satisfying functional customer requirements.
</p>
<p>A related case could be made for exception handling. For instance, rather than asserting the validity of an argument up-front and throwing an appropriate exception, the code may later fail with a NullReferenceException. Not throwing the exception up-front, close to where the actual error occurred, one will have a hard time tracking down the issue. Especially since a stack trace with symbols and line numbers is rarely available in a production environment.
</p>
<p>For someone having to resolve the issue, almost any clue as to the cause would be most welcomed. Without a clue that someone would walk around in the dark in the hope of stumbling into a solution.</p>
<h4>End users aren&#8217;t the only users<br />
</h4>
<p>As software developers we have to acknowledge that end users aren&#8217;t the only users of our software. System administrators, developers, and the like should also be factored in during development. Especially since the cost of instrumenting code at key places, early on, doesn&#8217;t add significantly to the overall development cost. Focusing on what can go wrong and communicating it well saves time, money, and frustration down the line. And as a bonus you might create better self-documenting code.
</p>
<p>That said it&#8217;s important to strike a balance between logging too little and too much information. A log should be detailed enough to reveal patterns of use. Ideally, the log should read like a story with short sentences detailing what&#8217;s about to happen, what did or didn&#8217;t happen, and possibly why.
</p>
<p>I&#8217;m not suggesting that we turn logging into a runtime version of <a href="http://en.wikipedia.org/wiki/Literate_programming">literate programming</a>. But simply that sufficient contextual information be provided, i.e., instead of logging &#8220;URL = &#8216;bugfree.dk&#8217;&#8221;, consider the more elaborate &#8220;Retrieving URL for indexing: &#8216;http://bugfree.dk&#8217;&#8221;.
</p>
<h4>Keep your statements clean<br />
</h4>
<p>On the other hand, log statements shouldn&#8217;t be immune to the <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY principle</a>. So make sure to have the logging framework automatically capture common bits of contextual information, such as the date and time of the entry and the class and method within which the log statement originated. On a similar note, don&#8217;t explicitly log when a method is entered or existed. Instead, treat such a case as a cross-cutting concern and take an <a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming">Aspect Oriented</a> approach to logging it.
</p>
<p>Lastly, not every method requires (extensive) logging. Figuring out when and what to log is key. Debugging the application, fixing bugs, and experience should provide guidance into what&#8217;s useful to log.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2009/07/22/basic-logging-guidelines/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Basic unit testing guidelines</title>
		<link>http://www.bugfree.dk/blog/2009/06/19/basic-unit-testing-guidelines/</link>
		<comments>http://www.bugfree.dk/blog/2009/06/19/basic-unit-testing-guidelines/#comments</comments>
		<pubDate>Fri, 19 Jun 2009 21:02:39 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Mocking]]></category>
		<category><![CDATA[Presentation]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Quality]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=111</guid>
		<description><![CDATA[Update, Nov 25, 2010: Rather than mimicking the directory structure of the assembly under test in a separate test assembly, I’m now more inclined to keep code under test and test code in the same assembly. Update, Aug 5, 2009: This post grew out of a couple of presentations that I did on the subject [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update, Nov 25, 2010:</strong> Rather than mimicking the directory structure of the assembly under test in a separate test assembly, I’m now more inclined to <a href="http://weblogs.asp.net/bsimser/archive/2008/04/09/unit-test-projects-or-not.aspx">keep code under test and test code in the same assembly</a>. </p>
<p><b>Update, Aug 5, 2009</b>: This post grew out of a couple of presentations that I did on the subject back in May and June. Here are my slides from <a href="http://www.bugfree.dk/blog/wp-content/uploads/2009/08/Unit-testing-and-mocking.pdf">The Unit testing and mocking presentation</a>. Among other things, they contain a few C# samples elaborating on some of the points below.</p>
<p>This post is born of the need to formalize a set of guidelines on how to write and organize tests. In the past I couldn’t help feeling that with the lack of guidelines I had to start over explaining my views on every new project. With no guidelines the tests written quickly grew unmaintainable, giving unit testing a bad name.</p>
<h4>Why unit test</h4>
<p>Unit testing done right helps build confidence in the code base and drives forward development. Both in terms of forcing one to reflect on the requirements by authoring tests, but also by providing a foundation for developing more modular and testable code.</p>
<p>Given the <a href="http://en.wikipedia.org/wiki/Cyclomatic_complexity">cyclomatic complexity</a> of even simple methods, however, not every path through a method is worth exercising with a test. Instead, focus on writing representative unit tests for good and bad scenarios.</p>
<h4>Unit test != integration test</h4>
<p>For object-oriented code a unit test is one that exercises a class in isolation, without the code under test relying on other classes to carry out its operation. Similarly, a unit test shouldn&#8217;t rely on the presence of a database or a key/value pair in a configuration file for it to run. If it did, it would be an integration test. Not that there&#8217;s anything wrong with integration tests. They just take on more dependencies and hence tend to be more brittle. And so they cause more false positives because some dependent part isn&#8217;t properly configured. The key point, though, is not to confuse unit testing with integration testing.</p>
<p>Typically, an object delegates part of its operation to other objects. Writing modular and testable code therefore involves the application of design patterns, such as <a href="http://www.martinfowler.com/articles/injection.html#SignificantRevisions">Inversion of Control (IoC)</a>. With IoC a test can inject (fake) components into the object under test. The fake components share their interfaces with the real ones, but the test controls how they interact with the object under test and hence how the object under test behaves.</p>
<h4>Keep up quality</h4>
<p>As tests are written it&#8217;s vital for the understandability and maintainability of the test suite to keep them small and focused. As a rule of thumb a test should amount to no more than 10-15 lines of code. Longer tests are indicative of too much functionality being tested at once or that code common to multiple tests should be refactored into helper methods.</p>
<p>In terms of quality, the code comprising the tests should be of production code quality, i.e., the code must be kept clean and refactored as the need arises. Otherwise, tests will start to emit the <a href="http://martinfowler.com/bliki/CodeSmell.html">classic code smells</a>. In the longer run code smells lead to tests that are not maintainable and for the time that went into writing them to be wasted.</p>
<h4>Organizing test code</h4>
<p>Assuming the use of Visual Studio (VS), for each VS project with code that one wants to test, create matching projects that host the various kinds of tests, i.e., for the Acme.Intranet.Search project, create the following test related projects:</p>
<pre>Acme.Intranet.Search.Common
Acme.Intranet.Search.UnitTest
Acme.Intranet.Search.IntegrationTest</pre>
<p>The Acme.Intranet.Common project is optional and may include code that is shared between test projects, such as custom assertions. As for the Acme.Intranet.Search.UnitTest project it should be fairly self-contained. One should be able to move the common assembly, the test assembly, and the business code assembly to another machine and have the tests execute there without further setup. Should a test rely on, say, a data file with test data, then include the file as an embedded resource within the test assembly.</p>
<p>Finally, within each test project, a class should be created for each class under test. In addition, the directory structure should match the namespace structure of the class under test, e.g., suppose the fully qualified name of a class is Acme.Intranet.Search.Business.Crawler, then create the following directory structure within the test assembly:</p>
<pre>Acme.Intranet.Search.UnitTest
    Acme
        Intranet
            Search
                Buesiness
                    CrawlerTest.cs</pre>
<p>While it’s important to write tests, it’s even more important to know where to put and find tests for a given functional area.</p>
<h4>Naming tests</h4>
<p>As far as naming and structure goes, a test should look something along these lines:</p>
<pre class="prettyprint lang-cs">[TestClass]
public class SomeClassTest {
    [TestMethod]
    public void SomeMethod_should_set_error_message_when_no_connection_string_is_configured() {
        // arrange
        // act
        // assert
    }
}</pre>
<p>The test should generally start with the name of the method or property being tested, followed by the word &quot;should&quot; followed by the successful outcome in a descriptive form. Because names of tests tend to be longer than those of regular methods, underscores are used for ease of readability. In addition, the body of most tests should be composed of three parts: (1) the arrange part that sets up the object under test and possibly injects fake dependencies into it. (2) The act part then exercises the method under test, and finally (3) the assert part that verifies that expected state and/or behavioral changes did indeed take place.</p>
<h4>Gathering metrics</h4>
<p>Whenever a build is kicked of (on a build server) it should exercise all tests. Should a test fail, it should cause the entire build to fail, stressing the importance of keeping tests green at all times. Furthermore, a build report should include basic metrics such as code coverage, number of tests run, time spend running the tests, and so forth.</p>
<p>Keep in mind, though, that a high degree of code coverage isn&#8217;t a goal in itself. Instead, focus on writing solid, focused, and representative tests that eventually drive up code coverage.</p>
<h4>Tooling</h4>
<p>As far as .Net and tooling goes, <a href="http://en.wikipedia.org/wiki/MSTest">MSTest</a> or <a href="http://nunit.org">NUnit</a> should be used in concert with <a href="http://www.bugfree.dk/blog/2009/02/11/an-example-of-unit-testing-using-typemock">TypeMock</a> or <a href="http://ayende.com/projects/rhino-mocks.aspx">Rhino Mocks</a>. The use of TypeMock may be preferred over Rhino Mocks because of its unique approach to mocking. TypeMock doesn&#8217;t create fake objects by emitting MSIL and dynamically loading a runtime-generated assembly into the test runner. Instead, TypeMock hooks into the CLR APIs and intercepts calls as the unit test executes. From a coding point of view the TypeMock approach may not change much, but from a functionality point of view it enables the testing of legacy code or new code not written with IoC in mind.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2009/06/19/basic-unit-testing-guidelines/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Jumping through loops with XSL</title>
		<link>http://www.bugfree.dk/blog/2009/06/13/jumping-through-loops-with-xsl/</link>
		<comments>http://www.bugfree.dk/blog/2009/06/13/jumping-through-loops-with-xsl/#comments</comments>
		<pubDate>Sat, 13 Jun 2009 21:25:46 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Xsl]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2009/06/13/jumping-through-loops-with-xsl/</guid>
		<description><![CDATA[I was recently faced with the need to express a loop in XSL. Not the build-in for-each that iterates over nodes matching an XPath, but one with a counter. In C# this kind of loop is easily expressed as for (int i = 0; i &#60; 5; i++) // do something No such for-construct exists [...]]]></description>
			<content:encoded><![CDATA[<p>I was recently faced with the need to express a loop in <a href="http://en.wikipedia.org/wiki/Xsl">XSL</a>. Not the build-in <a href="http://www.w3schools.com/XSL/el_for-each.asp">for-each</a> that iterates over nodes matching an <a href="http://en.wikipedia.org/wiki/XPath">XPath</a>, but one with a counter. In C# this kind of loop is easily expressed as</p>
<pre class="prettyprint lang-cs">
for (int i = 0; i &lt; 5; i++)
    // do something
</pre>
<p>No such for-construct exists in XSL. In fact there&#8217;re no looping constructs of any kind in XSL, except for the one used to iterate nodes. However, since XSL and C# are both <a href="http://en.wikipedia.org/wiki/Turing_complete">Turing complete</a> languages, and since anything that can be expressed in one Turing complete language can be expressed in another, it follows that it must be possible to express a loop with a counter in XSL.</p>
<p>But as <a href="http://en.wikipedia.org/wiki/Alan_Perlis">Alan Parlis</a> puts it in <a href="http://www-pu.informatik.uni-tuebingen.de/users/klaeren/epigrams.html">Epigrams on Programming</a>:</p>
<blockquote><p>Beware of the <a href="http://en.wikipedia.org/wiki/Turing_tar_pit">Turing tar-pit</a> in which everything is possible but nothing of interest is easy.</p>
</blockquote>
<p>Although XSL and C# are both Turing complete languages, XSL is a <a href="http://en.wikipedia.org/wiki/Functional_programming">functional programming language</a> and therefore belongs to a strain of languages that forgo build-in looping constructs. Instead, looping is accomplished through recursion.</p>
<p>We can turn the iterative C# loop into a recursive one like so:</p>
<pre class="prettyprint lang-cs">
void Loop(int i) {
    if (i &gt; 0) {
        // do something
        Loop(i - 1);
    }
}  
</pre>
<p>and transform the recursive solution into an XSL template:</p>
<pre class="prettyprint lang-xsl">
&lt;xsl:template name="Loop"&gt;
    &lt;xsl:param name="i" select="5"/&gt;
    &lt;xsl:if test="$i &gt; 0"&gt;
        &lt;!-- do something --&gt;
        &lt;xsl:call-template name="Loop"&gt;
            &lt;xsl:with-param name="i" select="$i - 1"/&gt;
        &lt;/xsl:call-template&gt;
    &lt;/xsl:if&gt;
&lt;/xsl:template&gt;
</pre>
<p>Okay, but what about nested loops then:</p>
<pre class="prettyprint lang-cs">
for (int i = 0; i &lt; 5; i++)
    for (int j = 0; j &lt; 5; j++)
        // do something
</pre>
<p>Giving it some thought, the nested loops (of any nesting level) can be expressed using recursion following a pattern of nested if-statements:</p>
<pre class="prettyprint lang-cs">
void NestedLoops(int i, int j, int k) {
    if (i &gt; 0) {
        // do something
        if (j == 1)
            NestedLoops(i - 1, k, k);
        else
            NestedLoops(i, j - 1, k);
    }
}
</pre>
<p>Again, performing a one-to-one transformation to XSL:</p>
<pre class="prettyprint lang-xsl">
&lt;xsl:template name="NestedLoops"&gt;
    &lt;xsl:param name="i"/&gt;
    &lt;xsl:param name="j"/&gt;
    &lt;xsl:param name="k"/&gt;
    &lt;xsl:if test="$i &gt; 0"&gt;
        &lt;!-- do something --&gt;
        &lt;xsl:choose&gt;
            &lt;xsl:when test="$j = 1"&gt;
                &lt;xsl:call-template name="NestedLoops"&gt;
                    &lt;xsl:with-param name="i" select="$i - 1"/&gt;
                    &lt;xsl:with-param name="j" select="$k"/&gt;
                    &lt;xsl:with-param name="k" select="$k"/&gt;
                &lt;/xsl:call-template&gt;
            &lt;/xsl:when&gt;
            &lt;xsl:otherwise&gt;
                &lt;xsl:call-template name="NestedLoops"&gt;
                    &lt;xsl:with-param name="i" select="$i"/&gt;
                    &lt;xsl:with-param name="j" select="$j - 1"/&gt;
                    &lt;xsl:with-param name="k" select="$k"/&gt;
                &lt;/xsl:call-template&gt;
            &lt;/xsl:otherwise&gt;
        &lt;/xsl:choose&gt;
    &lt;/xsl:if&gt;    
&lt;/xsl:template&gt;
</pre>
<p>Wordy, but seeing through the angle brackets I find solution quite elegant.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2009/06/13/jumping-through-loops-with-xsl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The rise and fall of WordPerfect</title>
		<link>http://www.bugfree.dk/blog/2009/05/31/the-rise-and-fall-of-wordperfect/</link>
		<comments>http://www.bugfree.dk/blog/2009/05/31/the-rise-and-fall-of-wordperfect/#comments</comments>
		<pubDate>Sun, 31 May 2009 10:24:52 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Book]]></category>
		<category><![CDATA[History]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2009/05/31/the-rise-and-fall-of-wordperfect/</guid>
		<description><![CDATA[A blog post pointed me to Pete Peterson&#8217;s Almost Perfect. The book details the rise and fall of WordPerfect (the software and the company), and is a great testimony to the earlier days of the industry. It&#8217;s the story of how a legendary company came to be and how it still shapes the world of [...]]]></description>
			<content:encoded><![CDATA[<p>A <a href="http://www.codinghorror.com/blog/archives/001252.html">blog post</a> pointed me to Pete Peterson&#8217;s <a href="http://www.wordplace.com/ap/index.shtml">Almost Perfect</a>. The book details the rise and fall of WordPerfect (the software and the company), and is a great testimony to the earlier days of the industry. It&#8217;s the story of how a legendary company came to be and how it still shapes the world of word processing to this day.
</p>
<p>Consider the state of computer-based word processing in 1977 when WordPerfect was conceived of. Afraid that word processors would interfere with so-called important applications, companies did word processing on dedicated mini-computers and mainframes. These machines were operated by a word processing department of employees that typed up documents. It wasn&#8217;t until the IBM PC that corporate users began typing documents themselves.
</p>
<h4>The early years<br />
</h4>
<p>Pete&#8217;s way into WordPerfect &#8212; and his initial exposure to computers &#8212; was by way of his brother-in-law, <a href="http://en.wikipedia.org/wiki/Bruce_Bastian">Bruce Bastian</a>. Following Bruce&#8217;s computer science degree in 1978, Bruce joined <a href="http://en.wikipedia.org/wiki/Alan_Ashton_(executive)">Alan Ashton</a> to realize Alan&#8217;s vision of a word processor for a <a href="http://en.wikipedia.org/wiki/Data_General">Data General</a> mini-computer. It was then, in 1979, that Pete joined the two as office manager. By 1992, when forced to leave WordPerfect, he&#8217;d turned vice president of marketing.
</p>
<p>Alan&#8217;s unique ideas involved crafting a word processor that didn&#8217;t require entering codes to format and layout documents. Compared to HTML authoring of today, contemporary word processors required the author to mix text and codes. Like tags in HTML, the codes described properties of the document, such as margins, line feeds, and emphasized text, and were specific to each product. Alan&#8217;s word processor, although character-oriented by nature, was to display the underlying codes using textual effects, creating a rough WYSIWYG experience.
</p>
<p>Other innovative features included the ability to scroll through a document line by line, rather than page by page, and non-modal editing. Contemporary word processors required the author to switch between command and text modes the way the <a href="http://en.wikipedia.org/wiki/Vi">Vi</a> family of editors still do. Without menus, modes made it easier to separate commands from text. Nonetheless, WordPerfect was modeless and hence characters could be typed in anywhere and anytime.
</p>
<p>In the late seventies, word processors (and operating systems) were largely written in assembler and hence required rewriting for each hardware platform. Up until the IBM PC version, assembler also dominated WordPerfect, which made it a challenge to maintain considering the plethora of supported platforms. Migrating to higher-level languages had been considered, but was discarded on the premise that it would result in slower applications with bigger memory footprints. On that note, it appears we haven&#8217;t learned as we keep rewriting the same fundamental applications and frameworks. Not in assembler, but in higher-level languages.
</p>
<h4>Microsoft catching up<br />
</h4>
<p>The 1981 introduction of the <a href="http://en.wikipedia.org/wiki/IBM_PC">IBM PC</a> pawed the way for a shift in the way software was developed and marketed. For vendors, the common architecture made lock-ins harder, yet provided access to a size of user base never before seen. WordPerfect was quick to seize the opportunity and released WordPerfect for the IBM PC in 1982.
</p>
<p>Although the software marked for the IBM PC was dominated by Microsoft, for years Word (and other word processors) couldn&#8217;t keep up with the features and sales of WordPerfect. Two technologies, however, enabled Microsoft to overtake WordPerfect: laser printers and graphical user interfaces. For years WordPerfect had supported a few laser printers and had only a text-based interface. By 1987, though, it had become clear that graphical user interfaces was the future. It just wasn&#8217;t obvious weather Windows, of which <a href="http://en.wikipedia.org/wiki/Windows_2.0">version 2</a> had just been released or <a href="http://en.wikipedia.org/wiki/OS/2">OS/2</a>, whose development was announced that year, or some other vendor would end up dominating the market.
</p>
<h4>The final years<br />
</h4>
<p>Moving from text to graphics posed a challenge for WordPerfect. Under DOS, the operating system provided only rudimentary services for drawing on the screen. For proportional font and image rendering, WordPerfect would itself have to take on rendering or use the services of a graphical user interface. But since it wasn&#8217;t clear whether Windows, OS/2, or some third environment were to dominate the future, WordPerfect decided to only augment the text-based interface with a graphical preview page. At the same time Microsoft released its first version of Word for Windows 2.0, relying on Windows for proportional font rendering, image display, and decent laser printer support.
</p>
<p>In light of present knowledge, it&#8217;s all too easy to pass judgment on past decisions. Nevertheless, it appears that the inability of WordPerfect to keep their eyes on the rolling ball had caused Microsoft to take over by the early nineties. Instead of focusing on WordPerfect for Windows, substantial resources went into developing versions of WordPerfect for other platforms, developing a spreadsheet and a database application, and many more.
</p>
<p>For years the availability of WordPerfect on almost any conceivable platform had supported the growth of the company. Now, the inability to cut losses and retain focus dragged WordPerfect into oblivion.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2009/05/31/the-rise-and-fall-of-wordperfect/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wireless routers wreaking havoc on LAN</title>
		<link>http://www.bugfree.dk/blog/2009/05/18/wireless-routers-wreaking-havoc-on-lan/</link>
		<comments>http://www.bugfree.dk/blog/2009/05/18/wireless-routers-wreaking-havoc-on-lan/#comments</comments>
		<pubDate>Mon, 18 May 2009 18:07:00 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Networking]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2009/05/18/wireless-routers-wreaking-havoc-on-lan/</guid>
		<description><![CDATA[With the ubiquity of wireless routers follow a surprising network instability issue. It turns out that wireless routers at many of the 330 apartments connected to network where I live bring with them rogue DHCP servers that make the network unstable. Non-authoritative DHCP servers on the network have posed a challenge for years. At first, [...]]]></description>
			<content:encoded><![CDATA[<p>With the ubiquity of wireless routers follow a surprising network instability issue. It turns out that wireless routers at many of the 330 apartments connected to network where I live bring with them rogue DHCP servers that make the network unstable.
</p>
<p>Non-authoritative DHCP servers on the network have posed a challenge for years. At first, I attributed the DHCP servers to badly configured Windows machines. However, the number of DHCP servers suggested that another explanation might be closer to the truth. Users accidentally installing DHCP servers are just not that common, and inspecting a couple of machines in question they were acquitted. What else could be the source of the DHCP traffic, then? Common to the machines were that wireless routers sat between them and the LAN.
</p>
<p>After much investigation, it turns out that a lot, if not all, wireless routers expose their DHCP server on all ports of the router, when it&#8217;s only necessary to expose it on inward-facing ports. I guess vendors don&#8217;t bother limiting the exposure because generally it&#8217;s of no concern to consumers. ISPs provide the wireless router with the necessary configuration parameters (IP address, subnet mask, default gateway, DNS servers, and so on) in addition to blocking DHCP traffic originating from the wireless router.
</p>
<p>On our network &#8212; equipped with eight aging 48-port <a href="http://www.cisco.com/en/US/products/hw/switches/ps637/">Cisco Catalyst 3500 XL</a> switches &#8212; DHCP traffic cannot be prevented from escaping the wireless router and making its way into the switches and onto LAN. The configuration parameters of rogue DHCP servers, intended for internal use only, are transmitted to external DHCP clients. Clients for which the supplied gateway, DNS server, and so on are only internally available. The DHCP client, unable to discern the rogue servers from the authoritative one, passes the parameters on to the network stack, setting itself up for network disconnectivity.
</p>
<p>The essence of the issue is that whenever a client requests configuration parameters, it, by definition of the <a href="http://tools.ietf.org/html/rfc2131">DHCP protocol</a>, broadcasts a message to be picked up by any DHCP server on the network. The client then awaits an offering of configuration parameters from one or more DHCP servers. Then, still according to specification, the DHCP client may use any strategy to accept one of several offerings. I can only guess as to how Windows makes its decision, but randomness and first responder probably play a key role. In any event, Windows may keep accepting offerings from rogue DHCP servers regardless of the number of times I command the IP configuration to &#8220;ipconfig /release&#8221; and &#8220;ipconfig /renew&#8221;.
</p>
<p>How to counteract rogue DHCP servers? There&#8217;re only a limited set of options: hard-coding the configuration parameters of individual machines, establishing <a href="http://en.wikipedia.org/wiki/VLAN">VLAN</a>s so computers become invisible to each other, or replacing the Cisco Catalyst 3500 switches with contemporary switches that are able to suppress DHCP traffic travelling the wrong way.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2009/05/18/wireless-routers-wreaking-havoc-on-lan/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Generating 2D random fractal terrains with F#</title>
		<link>http://www.bugfree.dk/blog/2009/03/06/generating-2d-random-fractal-terrains-with-f/</link>
		<comments>http://www.bugfree.dk/blog/2009/03/06/generating-2d-random-fractal-terrains-with-f/#comments</comments>
		<pubDate>Thu, 05 Mar 2009 22:14:48 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[F#]]></category>
		<category><![CDATA[Math]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2009/03/06/generating-2d-random-fractal-terrains-with-f/</guid>
		<description><![CDATA[In Generating 2D random fractal terrains with C# I implemented 1D midpoint displacement in an imperative language. Since I&#8217;m currently making my way through Robert Pickering&#8216;s Foundations of F#, in this post I want to redo it in F#. The first step along the way is the maxDisplacements function that, given a number of splits [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://www.bugfree.dk/blog/2009/02/23/generating-2d-random-fractal-terrains-with-c">Generating 2D random fractal terrains with C#</a> I implemented 1D midpoint displacement in an imperative language. Since I&#8217;m currently making my way through <a href="http://strangelights.com/blog">Robert Pickering</a>&#8216;s <a href="http://www.amazon.com/dp/1590597575?tag=strangelights-20&amp;camp=14573&amp;creative=327641&amp;linkCode=as1&amp;creativeASIN=1590597575&amp;adid=1T0HP42WA17EB83RZNFC&amp;">Foundations of F#</a>, in this post I want to redo it in F#.</p>
<p>The first step along the way is the maxDisplacements function that, given a number of splits of line segments, returns a list of maximum displacements. Here <a href="http://en.wikipedia.org/wiki/List_comprehension">list comprehension</a> comes in handy as a way to generate maximum displacements where the next is half of that of the previous, starting with 0.5:</p>
<pre class="prettyprint lang-fs">let maxDisplacements n = [for i in 1 .. n -&gt; 2.0**(float)(-i)]
</pre>
<p>Next is the composeCoordinates function whose job it is to infer the x coordinates from the y coordinates. When splitting line segments, as defined later by the split function, only y coordinates need to be dealt with. But for displaying the result as a list of points, e.g., as input to a graphing program, composeCoordinates generates the (x, y) coordinate pairs given a list of y coordinates. Again list comprehension is used to uniformly distribute the x coordinates in the range 0 to 1. Next, the x and y coordinates are fused using the build-in zip function, i.e., [x1; x2] and [y1; y2] become [(x1, y1); (x2, y2)].</p>
<pre class="prettyprint lang-fs">
let composeCoordinates (ys : list&lt;float&gt;) =
    let dx = 1.0 / (float)(ys.Length - 1)
    let xs = [for x in 0 .. ys.Length - 1 -&gt; (float)x * dx]
    List.zip xs ys
</pre>
<p>Now for the crux of the fractal generation process: the split function. As is customary with functional languages, looping is done using recursion and split is no exception. Passing in a list of y coordinates, a maximum displacement as generated by maxDisplacements, and a random number generator, split is defined as:</p>
<pre class="prettyprint lang-fs">
let rec split (ys : list&lt;float&gt;) displacement (random : Random) =
    match ys with
    | a :: b :: tail -&gt; 
        let m = b - a / 2.0
        let r = random.NextDouble() * displacement
        a :: a + m + r :: split (b :: tail) displacement random
    | a -&gt; a
</pre>
<p>Using <a href="http://en.wikipedia.org/wiki/Pattern_matching">pattern matching</a>, an if-then-else construct on steroids, split examines its input of y coordinates to determine if the inductive or the base case of the recursive implementation needs to be invoked. The first pattern matches a list starting with elements a and b following by zero or more elements. In case this pattern matches, a new list is returned. It&#8217;s composed of the original a element, a new displaced element, the original b element, and split applied to the original list with its first element removed. Removing one element at a time, at some point only one element is left in the list in which case the base case is invoked. When this happens, all the original line segments have been split in two.</p>
<p>Finally, the main function ties together the previous ones. Given an initial line segment, the number of times to apply split to it, and a random number generator, the actual splitting is done using the build-in <a href="http://en.wikipedia.org/wiki/Fold_(higher-order_function)">fold_left</a> function. fold_left is an example of <a href="http://codebetter.com/blogs/matthew.podwysocki/archive/2009/02/14/fun-with-folds.aspx">fun with folds</a> and a function that is itself recursively defined to make looping implicit.</p>
<pre class="prettyprint lang-fs">
let main() =
    let initial = [0.0; 0.0]
    let splits = 8
    let r = new Random()
    let ys = List.fold_left (fun s d -&gt; split s d r) initial (maxDisplacements splits) 
    print_any (composeCoordinates ys)
</pre>
<p>While initially hard to grog, the use of fold_left becomes clearer when applied to a list of integers to compute their product. Of the three arguments to fold_left the first is a function defined by a lambda expression (here the predefined multiplication operator is also applicable but less explicit). The second argument is the initial value of an accumulator. And finally, the third argument is the list to work on.</p>
<pre class="prettyprint lang-fs">
List.fold_left (fun x y -&gt; x * y) 1 [1;2;3]
List.fold_left (*) 1 [1;2;3]
</pre>
<p>What fold_left does is recursively call itself passing along the first argument as is. The second argument is the new value of the accumulator, computed by passing to the function of the first argument the original value of the accumulator and the first element of the list. That way it&#8217;s up to the function passed as the first argument to decide what operation to apply to the elements in the list. The third argument is the original list with the first element removed. The recursive chain of calls with their arguments then takes on this form:</p>
<pre class="prettyprint lang-fs">
List.fold_left (fun 1 1 -&gt; 1 * 1) 1 [1;2;3]
List.fold_left (fun 1 2 -&gt; 1 * 2) 1 [2;3]
List.fold_left (fun 2 3 -&gt; 2 * 3) 2 [3]
</pre>
<p>Within the main function the first argument to fold_left is a lambda expression that applies the split function to a list. The second argument, the accumulator, isn&#8217;t a scalar like with the product example, but a list of line segments to be passed to split. Finally, the third argument is the maximum displacement list. And so for the original line segment to be split n times, n maximum displacements must be provided by the maxDisplacements function.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2009/03/06/generating-2d-random-fractal-terrains-with-f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Generating 2D random fractal terrains with C#</title>
		<link>http://www.bugfree.dk/blog/2009/02/23/generating-2d-random-fractal-terrains-with-c/</link>
		<comments>http://www.bugfree.dk/blog/2009/02/23/generating-2d-random-fractal-terrains-with-c/#comments</comments>
		<pubDate>Mon, 23 Feb 2009 00:11:37 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Math]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2009/02/23/2d-fractal-terrain-generation-using-midpoint-displacement/</guid>
		<description><![CDATA[Back in 1999, when I was learning C++ and MFC, I remember spending a great deal of time writing an application that displayed the Mandelbrot set, probably the most famous of all fractals. And when I learned Remote Procedure Call, I even converted the application into a distributed Mandelbrot generator (which made sense given the [...]]]></description>
			<content:encoded><![CDATA[<p>Back in 1999, when I was learning C++ and MFC, I remember spending a great deal of time writing an application that displayed the <a href="http://en.wikipedia.org/wiki/Mandelbrot_set">Mandelbrot set</a>, probably the most famous of all fractals. And when I learned Remote Procedure Call, I even converted the application into a distributed Mandelbrot generator (which made sense given the CPU speed of the time).</p>
<p>What’s so fascinating about the Mandelbrot set, and other fractals, is that the often simple equations that define them are able to give birth to such complex creations.</p>
<p>In general, a <a href="http://en.wikipedia.org/wiki/Fractal">fractal</a> is defined as:</p>
<blockquote><p>“[…] &#8216;a rough or fragmented <a href="http://en.wikipedia.org/wiki/Shape">geometric shape</a> that can be split into parts, each of which is (at least approximately) a reduced-size copy of the whole,&#8217; a property called <a href="http://en.wikipedia.org/wiki/Self-similarity">self-similarity</a>. A fractal often has the following features: it has a fine structure at arbitrarily small scales; it is too irregular to be easily described in traditional <a href="http://en.wikipedia.org/wiki/Euclidean_geometry">Euclidean geometric</a> language; it is self-similar (at least approximately or <a href="http://en.wikipedia.org/wiki/Stochastic">stochastically</a>); [… and] it has a simple and <a href="http://en.wikipedia.org/wiki/Recursive_definition">recursive definition</a>. […] Natural objects that approximate fractals to a degree include clouds, mountain ranges, lightning bolts, coastlines, and snowflakes.”</p>
</blockquote>
<p>The Mandelbrot set is an example of a fractal whose definition contains no stochastic element, i.e., the fractal looks the same every time it’s generated. Recently, though, I came across a simple  algorithm that claimed to generate fractal terrains by adding randomness to the equation. So, given my history with fractals, I wanted to play with the algorithm that&#8217;s based on progressive refinement through <a href="http://gameprogrammer.com/fractal.html#midpoint">midpoint displacement in one dimension</a>:</p>
<pre>
Start with a single horizontal line segment
Repeat for a sufficiently large number of times
    Repeat over each line segment
        Find the midpoint of the line segment
        Displace the midpoint in y by a random amount
    Reduce the range for random numbers
</pre>
<p>Here’s my implementation of the algorithm in C#:</p>
<pre class="prettyprint lang-cs">
using System;
using System.Collections.Generic;

namespace FractalTerrain {
    class Point {
        public double x;
        public double y;
    }

    class Program {
        static void Main(string[] args) {
            int iterations = 8;
            double roughness = 0.5;
            double displacementFactor = 1.0;
            Random generator = new Random();
            double[] ys = { 0.0, 0.0 };

            for (int i = 0; i < iterations; i++) {
                ys = Split(ys, displacementFactor, generator);
                displacementFactor *= roughness;
            }

            Point[] points = ComposeCoordinatePairs(ys);
            foreach (Point p in points) {
                Console.WriteLine("{0:0.000} {1:0.000}", p.x, p.y);
            }
        }

        static double[] Split(double[] ys, double displacementFactor, Random generator) {
            double[] newYs = new double[2 * ys.Length - 1];

            for (int i = 0; i < ys.Length - 1; i++) {
                double midpoint = (ys[i] + ys[i + 1]) / 2.0;
                double displacement = generator.NextDouble() * displacementFactor;
                newYs[2 * i] = ys[i];
                newYs[2 * i + 1] = midpoint + displacement;
            }

            return newYs;
        }

        static Point[] ComposeCoordinatePairs(double[] ys) {
            double increment = 1.0 / (ys.Length - 1);
            Point[] points = new Point[ys.Length];

            for (int i = 0; i < ys.Length; i++) {
                points[i] = new Point();
                points[i].x = increment * i;
                points[i].y = ys[i];
            }

            return points;
        }
    }
}
</pre>
<p>Splitting line segments, the C# code doesn't store the x-component of the coordinate pairs because it can be inferred from the number of y-components and the fact that x-components go from 0 to 1, both inclusive. Hence, starting with the line segment (0,0)-(1,0), the code splits it by calling the Split method passing in a list of y-components of the line segment. After the first iteration the single line segment becomes two, then four, then eight, and so on until the line segments have undergone eight iterations of splitting. Generally, after the i'th iteration the number of line segments is 2^i and so after eight iterations we end with 256 line segments.</p>
<p>As prescribed by the algorithm, merely splitting line segments doesn’t give rise to a mountain. The mountain emerges because each time a line segment is split in two, a random displacement is added to the y-component at the center of the line segment. Assigning an upper limit to the maximum displacement within an iteration is what defines the roughness of the generated terrain. For the above implementation, the maximum displacement is defined as half of that of the previous iteration starting with 0.5. Thus, the first couple of iterations roughly define the terrain and additional iterations fill in the details.</p>
<p>In animated form the transformations from two to 256 line segments looks like so:</p>
<p><img src="http://www.bugfree.dk/blog/wp-content/uploads/2009/02/a-ridgeline-emerges.gif" /></p>
<p>Among the practical applications of such a random fractal terrain generator are computer games. Not necessarily for generating 2D ridgelines, but for generating entire 3D terrains or even clouds. It works by generalizing 1D midpoint displacement to 2D in the form of the <a href="http://gameprogrammer.com/fractal.html#diamond">diamond-square algorithm</a>. Then a cloud, for instance, can be derived from the 3D terrain by applying a height map to it; a height map in which different heights get assigned different colors.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2009/02/23/generating-2d-random-fractal-terrains-with-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using VS linked files for strong naming assemblies</title>
		<link>http://www.bugfree.dk/blog/2009/02/17/using-vs-linked-files-for-strong-naming-assemblies/</link>
		<comments>http://www.bugfree.dk/blog/2009/02/17/using-vs-linked-files-for-strong-naming-assemblies/#comments</comments>
		<pubDate>Tue, 17 Feb 2009 21:43:39 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Tip]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2009/02/17/using-vs-linked-files-for-strong-naming-assemblies/</guid>
		<description><![CDATA[Visual Studio has the ability to add a file as a link, making other parts of Visual Studio believe the file is actually located where it&#8217;s added. One useful application of the link feature is for signing assemblies by way of a key file. Signing an assembly using a digital signature may serve one or [...]]]></description>
			<content:encoded><![CDATA[<p>Visual Studio has the ability to add a file as a link, making other parts of Visual Studio believe the file is actually located where it&#8217;s added. One useful application of the link feature is for signing assemblies by way of a key file. Signing an assembly using a digital signature may serve one or more purposes: It&#8217;s a precondition for deploying an assembly to the Global Assembly Cache (GAC), sharing an assembly among applications, and making <a href="http://msdn.microsoft.com/en-us/library/fdhkd3a5.aspx">side-by-side execution</a> possible. Also, signing an assembly is useful for asserting its integrity, GAC deployed or otherwise.</p>
<p>The reason for bringing up the linked file feature in conjunction with assembly signing is that to me the feature seems particularly well-suited for linking one and only key file into multiple Visual Studio projects. Yet people seem to be unaware of the feature and so common approaches to signing is to either create a new key file for each assembly &#8212; most likely because Visual Studio makes it so easy to create a new key file from the Project Settings dialog &#8212; or signing assemblies by creating one key file and then copy/paste it to other projects in the solution.</p>
<p>Below is an example from the GAC showcasing how assemblies related to <a href="http://research.microsoft.com/en-us/projects/pex/">Pex</a> naturally go together and are therefore signed using the same key (they share 76a274db078248c8, their public key token). The same goes for  assemblies relating to other Microsoft products, such as the ones comprising a particular version of the .Net framework (because of the side-by-side execution, different versions of .Net framework assemblies are signed using different keys). So why not apply the same principle to what you deploy to the GAC?</p>
<p><img src="http://www.bugfree.dk/blog/wp-content/uploads/2009/02/example-of-public-key-from-the-gac.png" /></p>
<p>While using the same key (copy or not) makes it possible to differentiate your assemblies from everyone else and for your <a href="http://en.csharp-online.net/.NET_CLR_Components%E2%80%94Assembly_Names">four-part assembly name</a> in web.config and spread around the code to be uniform &#8212; SharePoint developers often need to provide the four-part name for their assemblies to other parts of the solution &#8212; copying the key around is still a violation of the <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY principle</a> and as such is indicative of a <a href="http://martinfowler.com/bliki/CodeSmell.html">code smell</a>. More importantly, using the link feature of Visual Studio, there&#8217;s no reason to keep the bad smell around.</p>
<p>Assuming you&#8217;ve already created a solution (in Visual Studio 2008) and added a project to it, the way to share a key file is to first create one by right clicking a project in Solution Explorer and selecting Properties. Now click the Signing tab and check the Sign the assembly check box. The dropdown lets you create a new key file by selecting New and filling out the information in the Create Name Key window. Alternatively, a key file is created using <a href="http://msdn.microsoft.com/en-us/library/k5b5tt23.aspx">sn.exe</a>, the strong name utility that comes with the <a href="http://blogs.msdn.com/windowssdk/archive/2008/09/25/winsdk-in-vs2008-sp1-patch-what-changed.aspx">Microsoft Windows SDK</a>. On my machine, sn.exe is located in C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin and is invoked like so:</p>
<pre>
% sn -k MySharedKeyPair.snk
</pre>
<p>How the key file is created isn&#8217;t particularly relevant to the rest of this post. Just make sure to place the key file in a common location, e.g., the top-level directory holding the Visual Studio solution file. Now go to Solution Explorer, right click on your project, and select Add existing Item. Then locate the key file within the solution directory and make sure to click the arrow on the Add button and select Add as Link. Note how the file is added to the project and marked by an arrow indicating it&#8217;s a link:</p>
<p style="margin: 0px; padding: 0px;">
<img style="float:left;" src="http://www.bugfree.dk/blog/wp-content/uploads/2009/02/add-existing-item-as-link.png" />&nbsp;&nbsp;&nbsp;<img style="float:" src="http://www.bugfree.dk/blog/wp-content/uploads/2009/02/linked-file-in-solution-explorer.png" /></p>
<p>Returning to the Signing tab and selecting the dropdown, it now includes the linked key file. Don&#8217;t mind the absolute path; once you select MySharedKeyPair.snk, Visual Studio converts the path to a relative one (close and reopen the Signing tab and see for yourself). Also note that if you select Browse, the key file you select is copied to the project folder and added to the project as a regular file.</p>
<p><img src="http://www.bugfree.dk/blog/wp-content/uploads/2009/02/select-linked-file-in-signing-tab-of-project-properties.png" /></p>
<p>Another way to associate a key file with an assembly is through the <a href="http://msdn.microsoft.com/en-us/library/system.reflection.assemblykeyfileattribute.aspx">AssemblyKeyFile</a> attribute. The attribute instructs the compiler of where to look for the key file and, although not used by the runtime, the attribute is included in the assembly along with any other attribute for everyone to see.</p>
<p><img src="http://www.bugfree.dk/blog/wp-content/uploads/2009/02/key-file-attribute-in-assembly-info.png" /></p>
<p>Using AssemblyKeyFile is probably the simplest approach to sharing a key file between projects, but now compiling the assembly results in a compiler warning as displayed above. The <a href="http://msdn.microsoft.com/en-us/library/xh3fc3x0(VS.80).aspx">use of the AssemblyKeyFile attribute has been deprecated</a> by Microsoft because it may lead to you inadvertently disclosing sensitive information through the embedded path and because working with a relative path may confuse users and the build system (the relative path is retained in the assembly, though). However, it appears AssemblyKeyFile is still the preferred way for MS to sign their assemblies. Inspecting a couple of .Net 3.5 assemblies with Reflector, here&#8217;s what their AssemblyKeyFile looks like:</p>
<pre class="prettyprint lang-cs">
[assembly: AssemblyKeyFile(@"f:\\dd\\tools\\devdiv\\EcmaPublicKey.snk")]
[assembly: AssemblyKeyFile(@"f:\\dd\\tools\\devdiv\\35MSSharedLib1024.snk")]
[assembly: AssemblyKeyFile(@"f:\\dd\\tools\\devdiv\\FinalPublicKey.snk")]
...
</pre>
<p>To come full circle, the question of how Visual Studio, or rather MSBuild, actually signs an assembly using the information provided in the Properties dialog (real file or link) remains to be answered. Since a Visual Studio project file acts as input to MSBuild, we can see what&#8217;s going on under the hood of MSBuild by invoking a compile from the command line. On my machine <a href="http://msdn.microsoft.com/en-us/library/ms164311.aspx">msbuild.exe</a> is located in C:\Windows\Microsoft.NET\Framework\v3.5 and assuming you have a console window open with its current directory set to the directory of your project file, msbuild is invoked like so:</p>
<pre>
% msbuild /verbosity:diagnostic &gt; log.txt
</pre>
<p>Bring up log.txt in your favorite editor and eventually you&#8217;ll come across where <a href="http://msdn.microsoft.com/en-us/library/78f4aasd.aspx">csc.exe</a>, the C# compiler, is invoked:</p>
<p><img src="http://www.bugfree.dk/blog/wp-content/uploads/2009/02/key-file-and-msbuild.png" /></p>
<p>As you might have guessed, MSBuild carries over the location of the key file by passing the /keyfile argument to csc.exe.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2009/02/17/using-vs-linked-files-for-strong-naming-assemblies/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>An example of unit testing using TypeMock</title>
		<link>http://www.bugfree.dk/blog/2009/02/11/an-example-of-unit-testing-using-typemock/</link>
		<comments>http://www.bugfree.dk/blog/2009/02/11/an-example-of-unit-testing-using-typemock/#comments</comments>
		<pubDate>Wed, 11 Feb 2009 04:00:07 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Mocking]]></category>
		<category><![CDATA[Quality]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2009/02/11/an-example-of-unit-testing-using-typemock/</guid>
		<description><![CDATA[This post details my first use of TypeMock, a commercial mocking framework, for testing a web part that displays a dropdown bound to a LINQ query. Based on the item selected, the web part then displays a result bound to another LINQ query. For the purpose of becoming familiar with TypeMock, though, the focus of [...]]]></description>
			<content:encoded><![CDATA[<p>This post details my first use of <a href="http://www.typemock.com">TypeMock</a>, a commercial mocking framework, for testing a web part that displays a dropdown bound to a LINQ query. Based on the item selected, the web part then displays a result bound to another LINQ query. For the purpose of becoming familiar with TypeMock, though, the focus of this post is on testing the code that initializes the LINQ data context. It does so by reading a connection string from a configuration file and passing it to the data context.</p>
<p>In order to test code whose branching behavior depends on a value read from a configuration file, the test should provide various inputs and assert that the code under test acts accordingly. In addition, the test should run in milliseconds to encourage frequent runs and it should be self-contained, meaning no setup should be required before running the test. These requirements are best met with the web part running in a controlled environment. Yet, as far as the code under test goes, it should behave as if part of an Asp.Net page.</p>
<p>For the sake of brevity, here&#8217;s my web part with the code to initialize the data context:</p>
<pre class="prettyprint lang-cs">
public class MyWebPart : WebPart {
    MyDataContext _db;    /* LINQ database context */
    string _error;        /* Early stage error message */    	

    public MyWebPart() {
        Initialize();
    }

    private void Initialize() {
        string c = GetMyConnectionString();
        if (c == null)
            _error = "Unable to do something";
        else
            _db = new MyDataContext(c);
    }

    private string GetMyConnectionString() {
        System.Configuration.ConnectionStringSettings c = 
            System.Configuration.ConfigurationManager.
                ConnectionStrings["MyConnection"];
        return c == null ? null : c.ConnectionString;
    }
        
    protected override void Render(HtmlTextWriter w) {
        // display error message if set
    }
}
</pre>
<p>Notice how the constructor calls out to an Initialize method. Otherwise code within the constructor would fire before I&#8217;d have a chance to setup a controlled environment around the web part and I wouldn&#8217;t be able to test it. Turning the attention to Initialize itself, it’s made up of only a simple if statement. The idea is that if I can&#8217;t mock something as simple as reading a value from a configuration file, most likely I can&#8217;t mock something more involved either. On the other hand, for a developer already familiar with TypeMock and test first development, the code above may be born of the need to satisfy a failing test.</p>
<p>I want to test Initialize by controlling how GetMyConnectionString gets to return the connection string. While running in an Asp.Net context, GetMyConnectionString would attempt to read the string from web.config. Within my controlled environment, however, I want to inject into the web part an alternate implementation that returns a value of my choosing. That way I can control the path through Initialize and inspecting the state of the  _error or _db fields, I&#8217;m able to determine if the code behaved as intended.</p>
<p>Using the method chaining DSL of TypeMock, the test takes on this form (of course, having more tests, I&#8217;d move shared code into helper methods decreasing the test to code ratio):</p>
<pre class="prettyprint lang-cs">
[TestClass, ClearMocks]
public class MyWebPartTest {
    [TestMethod, Isolated, VerifyMocks]
    public void Should_set_error_message_when_no_
                connection_string_is_configured() {
        // arrange
        MyWebPart fake = Isolate.Fake.Instance&lt;MyWebPart&gt;();
        Isolate.NonPublic.WhenCalled(fake, 
            "Initialize").CallOriginal();
        Isolate.NonPublic.WhenCalled(fake, 
            "GetMyConnectionString").WillReturn(null);
        PrivateObject handle = new PrivateObject(fake);

        // act
        handle.Invoke("Initialize", null); 

        // assert
        Isolate.Verify.NonPublic.WasCalled(fake, 
            "GetMyConnectionString");
        string error = (string)handle.GetField("_error");
        MyDataContext ctx = (MyDataContext)handle.GetField("_db");
        Assert.AreEqual("Unable to do something", error);
        Assert.AreEqual(null, ctx);
    }
}
</pre>
<p>There&#8217;re three parts to tests using TypeMock: (1) the arrange part sets up expectations of what’s going to happen when a method, a property, or some other part of the code under test is invoked; (2) the act part carries out the actual interaction with the object under test, turning to <a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.privateobject.aspx">PrivateObject</a> to invoke the Initialize method; and finally (3) the assert part verifies that what was supposed to happen did happen. Worth noting is that this test asserts both state and behavior, i.e., as part of executing the code under test, _error or _db should&#8217;ve been set to an appropriate state and GetMyConnectionString should’ve been called once and only once.</p>
<p>This concludes my example, which I believe illustrates the basics of testing and mocking using MS Test and TypeMock. Comparing and contrasting TypeMock to <a href="http://weblogs.asp.net/rosherove/archive/2007/04/26/choosing-a-mock-object-framework.aspx">other popular mocking frameworks</a>, TypeMock has the distinct feature that it can mock almost anything, with or without using interfaces. <a href="http://www.mockobjects.com/2007/03/stop-designing-for-testability.html">Some</a> argue that not enforcing the use of interfaces is also the disadvantage of TypeMock, because for code to be truly testable, it should be modularized using the <a href="http://en.wikipedia.org/wiki/Inversion_of_control">Inversion of Control principle</a>. However, with legacy code, such as the .Net framework or the SharePoint API, to me TypeMock appears to bridge the two worlds nicely, leaving the developer in charge.</p>
<p>To learn more about the basic concepts of mocking, Inversion of Control, and Dependency Injection (containers), I&#8217;d recommend listening to a couple of <a href="http://altnetpodcast.com">Alt.Net podcasts</a>: <a href="http://altnetpodcast.com/episodes/5-di-and-ioc">Dependency Injection and Inversion of Control</a> and <a href="http://altnetpodcast.com/episodes/6-more-di-and-ioc">More Dependency Injection and Inversion of Control</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2009/02/11/an-example-of-unit-testing-using-typemock/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Computer activation with Asp.Net MVC</title>
		<link>http://www.bugfree.dk/blog/2008/10/22/computer-activation-with-aspnet-mvc/</link>
		<comments>http://www.bugfree.dk/blog/2008/10/22/computer-activation-with-aspnet-mvc/#comments</comments>
		<pubDate>Wed, 22 Oct 2008 18:50:02 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Asp.Net]]></category>
		<category><![CDATA[Networking]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2008/10/22/computer-activation-with-aspnet-mvc/</guid>
		<description><![CDATA[Download source or watch demo. (Other posts in this series include: Kernel space traffic shaping with Linux and User space traffic shaping with Ruby that touch exclusively on Linux issues.) This post covers an Asp.Net MVC application (for an overview of Asp.Net MVC, the Herding Code guys recently interviewed Phil Haack) I wrote that automates [...]]]></description>
			<content:encoded><![CDATA[<p>Download <a href="/software/AspNetMvcComputerActivation-1.0.zip">source</a> or watch <a href="http://www.bugfree.dk/blog/wp-content/uploads/2008/10/FilosofparkenComputerActivation.wmv">demo</a>.</p>
<p>(Other posts in this series include: <a href="http://www.bugfree.dk/blog/2007/11/18/kernel-space-traffic-shaping-with-linux">Kernel space traffic shaping with Linux</a> and <a href="http://www.bugfree.dk/blog/2008/04/12/user-space-traffic-shaping-with-ruby">User space traffic shaping with Ruby</a> that touch exclusively on Linux issues.)</p>
<p>This post covers an <a href="http://www.asp.net/mvc/">Asp.Net MVC</a> application (for an overview of Asp.Net MVC, the <a href="http://herdingcode.com">Herding Code</a> guys recently <a href="http://herdingcode.com/?p=75">interviewed</a> <a href="http://haacked.com">Phil Haack</a>) I wrote that automates the collection of information about computers and their owners on a local area network. The idea is to have the Internet gateway match the identity of each computer that wants to send traffic through it against a white list. Should the request originate from an unknown computer, the gateway redirects that computer to a web application for Internet access activation. Each user then has to create an account and provide verifiable contact information and/or associate their computer with an existing account.</p>
<p>With the contact information of every connected user, maintaining a network with 331 connected apartments, 371 users, and 513 privately owned computers becomes more manageable. Now you can easily email all users about general issues or individual users about specific issues, such as wireless routers exposing rogue DHCP servers or virus slowing down the network.</p>
<p>Without being able to contact a user, the best you can hope for is to use the MAC address to locate and disable the port on the switch to which the user is connected. But terminating network access without warning or explanation, the user has no way of knowing what hit him. Now when the user contacts you, figuring out if he&#8217;s experiencing network issues because of a closed port or something entirely different quickly becomes a challenge &#8212; and something that doesn&#8217;t scale well.</p>
<p><img src="http://www.bugfree.dk/blog/wp-content/uploads/2008/10/CreateAccount.png" /></p>
<p>That&#8217;s where the Asp.Net MVC application comes in. To get a feel for how the software accomplishes its task, you should watch the minute and a half <a href="http://www.bugfree.dk/blog/wp-content/uploads/2008/10/FilosofparkenComputerActivation.wmv">demo</a>. It portrays the browsing experience of a user connecting his computer to the network for the first time and attempting to browse the web. Behind the scenes the Linux gateway uses its Netfilter capabilities to efficiently match the MAC address of each request against the white list. With no match for the computer just connected, upon browsing the web, Netfilter redirect the user&#8217;s browser to the web application. Then, every so often, using a Ruby script, the gateway queries the web server for updates to the white list and carries over the changes to Netfilter.</p>
<h4>Database schema</h4>
<p>The web application is based on the idea that a user is responsible for zero or more computers. Focusing on the web application, rather than the Linux part, the rest of this post highlights a few features that use and manipulate the data structures stored in a MS SQL Server Express database:</p>
<p><img src="http://www.bugfree.dk/blog/wp-content/uploads/2008/10/ERDiagram.png"></p>
<h4>Reverse lookup of MAC</h4>
<p>Establishing an ownership between a user and a computer is done via the MAC address of the computer. Now, it wouldn&#8217;t be particularly user friendly if the user had to go about locating the MAC address and manually typing it into a web form. Instead, the web application looks up the user&#8217;s MAC address within the ARP cache of the web server.</p>
<p><img src="http://www.bugfree.dk/blog/wp-content/uploads/2008/10/ActivatedComputers.png"></p>
<p>Because the user&#8217;s computer and the web server are both on the same local network and because they&#8217;re already exchanging data (the user is visiting a web page hosted on the server), the parties are effectively communicating through the ARP protocol of the data link layer. The data entry form is therefore able to present the user with a control that makes associating computers to the account easy. By reverse lookup, the computer currently browsing the web application is indicated by &#8220;Now logged in from here&#8221;.</p>
<h4>Email verification</h4>
<p>Most users don&#8217;t mind handing over basic information such as their email address. And as users are blocked from accessing the Internet, at the time of entry we only validate the email address for syntactic correctness.</p>
<p><img src="http://www.bugfree.dk/blog/wp-content/uploads/2008/10/VerificationEmail.png"></p>
<p>A few users, however, repeatedly entered fake email addresses to gain Internet access. Consequently, we send out an email to the address, leaving open a 24 hour window for the user to follow a link. Otherwise, the software sends out a reminder email, marks the account as inactive, and redirects the user to the web application.</p>
<p><a href="http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx">Validating the syntax of email addresses</a> is done using regular expressions. As with most complex regular expressions, they&#8217;re hard to read and verify the correctness of. They do, however, stand the test against a database of hundreds of email addresses. To come full circle, though, what is needed is a way to match the domain part of the email address against the DNS MX record of the domain. Unfortunately, MX lookup isn&#8217;t build into the .Net framework.</p>
<h4>Unhalted exception emailing error handler</h4>
<p>Error handling deserves a <a href="http://www.bugfree.dk/blog/2008/08/30/aspnet-error-handling-by-httpmodule">post</a> on its own. Suffice it to say that to stay on top of any application, unhalted exceptions should be logged, or in this case, emailed to a designated address. Inevitably, users of your software will use it in unanticipated ways and so a global exception handler provides invaluable insight to learn from.</p>
<p><img src="http://www.bugfree.dk/blog/wp-content/uploads/2008/08/emailexceptionmoduleexample.png"><br /> (Summary part of example email. Click <a href="http://www.bugfree.dk/blog/wp-content/uploads/2008/08/emailexceptionmoduleexample.html" target="_blank">here</a> for complete output.)</p>
<h4>Download and maybe try out</h4>
<p>The web application was developed around February 2008; about the time the Asp.Net MVC framework went into Preview 2 and had started gaining momentum. Unfortunately, developing against this early a release, now the web application doesn&#8217;t run on a computer with .Net 3.5 SP1 installed.</p>
<p>There&#8217;s no problem compiling the application because the Preview 2 bits are in the bin folder of the application. But running the application generates an exception stating:</p>
<pre>
Could not load type 'System.Web.HttpContextWrapper2' from 
assembly 'System.Web.Abstractions' [located in the GAC]
</pre>
<p>That&#8217;s because the version of System.Web.Abstractions.dll that ships with .Net 3.5 SP1 no longer holds the HttpContextWrapper2 class. On a machine without .Net 3.5 SP1, however, Cassini runs the application just fine. Before running it, though, remember to create a database from the schema in Database.sql and point to that database from web.config.</p>
<p>Lastly, I should stress that the software is a prototype and served as a way for me to wrap my head around ASP.Net MVC and LINQ. So, the code may not win a beauty contest.</p>
<h4>Conclusion</h4>
<p>The activation software went online late March 2008. During the first couple of weeks I had to put in a couple of bug fixes based on what I learned from the unhalted exception emails. Since then, however, the software has served the purpose it was charged with.</p>
<p>The only issue that I haven&#8217;t been able to resolve is why, on rare occasions, redirecting a computer confuses its browser: if you visit a page and is redirected to the web application, for a short time after, the page keeps resolving to the web application. Most likely it&#8217;s a residual effect of the packet rewriting taking place on the gateway.</p>
<p>Another thing I wish I&#8217;d implemented was tracing to better understand how a couple of users got to experience a few exceptions that I don&#8217;t know how to interpret from the unhalted exception emails alone.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2008/10/22/computer-activation-with-aspnet-mvc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://www.bugfree.dk/blog/wp-content/uploads/2008/10/FilosofparkenComputerActivation.wmv" length="796345" type="video/x-ms-wmv" />
		</item>
		<item>
		<title>Asp.Net error handling by HttpModule</title>
		<link>http://www.bugfree.dk/blog/2008/08/30/aspnet-error-handling-by-httpmodule/</link>
		<comments>http://www.bugfree.dk/blog/2008/08/30/aspnet-error-handling-by-httpmodule/#comments</comments>
		<pubDate>Sat, 30 Aug 2008 21:58:29 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Asp.Net]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Quality]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2008/08/30/aspnet-error-handling-by-httpmodule/</guid>
		<description><![CDATA[Download EmailingExceptionModule-1.0.zip. In any real-world application, unhalted exceptions are an unavoidable fact of life. Such exceptions should occur relatively infrequently, but when they do some kind of supporting infrastructure better be in place to capture the when and why of the exceptions. As a developer, you should have the ability to perform a postmortem analysis [...]]]></description>
			<content:encoded><![CDATA[<p>Download <a href="/software/EmailingExceptionModule-1.0.zip">EmailingExceptionModule-1.0.zip</a>.</p>
<p>In any real-world application, unhalted exceptions are an unavoidable fact of life. Such exceptions should occur relatively infrequently, but when they do some kind of supporting infrastructure better be in place to capture the when and why of the exceptions. As a developer, you should have the ability to perform a postmortem analysis on what went wrong and learn from it. Paramount to such analysis is capturing and logging sufficient information at the point of failure.</p>
<p>What this post covers is the thoughts and development of an Asp.Net HttpModule that captures and emails such unhalted exception information to a designated email address.</p>
<p>To be clear, the goal of the EmailingExceptionModule isn&#8217;t to prevent unhalted exception from occurring per se. Within code, a developer may not know how to handle an exception, and so the exception should rightfully propagate the call stack. In case no caller steps in and handles the exception, the best choice is most likely to terminate the application. It&#8217;s almost always better to be upfront with the user than conceal the possibly inconsistent state of the application.</p>
<p>So when does the EmailingExceptionModule come in handy then? One scenario is that of <a href="http://msdn.microsoft.com/en-us/vcsharp/aa336812.aspx">C# unchecked exceptions</a>, where the compiler doesn&#8217;t force the caller to catch all types of exceptions thrown by the callee. Unchecked exceptions may materialize as type cast or null reference exceptions when accessing variables. What unchecked exceptions boil down to is that, given the <a href="http://en.wikipedia.org/wiki/Cyclomatic_complexity">cyclomatic complexity</a> of some methods, it&#8217;s impractical to manually work through every conceivable path of execution ahead of time. Another scenario is problems with the runtime environment, such as out of disk space or database server down. Nonetheless, some map of the path to failure is helpful in preventing others going down that same path.</p>
<p><img src="http://www.bugfree.dk/blog/wp-content/uploads/2008/08/emailexceptionmoduleexample.png" /><br /> (Summary part of example email. Click <a href="http://www.bugfree.dk/blog/wp-content/uploads/2008/08/emailexceptionmoduleexample.html" target="_blank">here</a> for complete output.)</p>
<p>With web applications, we can take advantage of the application running in a centralized environment. In the spirit of Microsoft&#8217;s <a href="http://en.wikipedia.org/wiki/Dr._Watson_(debugger)">Doctor Watson</a> technology, we can register our own web application error handler and hook it into the Http request pipeline, and have the application execute our code on unhalted exceptions. In practice, such an error handler is implemented either through the Application_Error method of an application&#8217;s <a href="http://en.wikipedia.org/wiki/Global.asax">Global.asax</a> or by loading an <a href="http://msdn.microsoft.com/en-us/library/bb398986.aspx">HttpModule</a> into the application.</p>
<p>Hinted by the title, I went for the HttpModule. The reason may best be understood by taking a peak behind the .Net curtains: Global.asax is a filename hardwired into the framework so that whenever an application is first hit, the framework asks HttpApplicationFactory, an internal <a href="http://www.ondotnet.com/pub/a/dotnet/2003/08/11/factorypattern.html">factory</a> class, for an <a href="http://msdn.microsoft.com/en-us/library/system.web.httpapplication.aspx">HttpApplication</a> representing the application (there&#8217;s a unique one for each virtual application). As part of manufacturing the HttpApplication, the factory locates the application&#8217;s Global.asax, compiles it into a dynamically generated DLL, loads the DLL, and reflects over the Global.asax class looking for methods adhering to the convention of modulename_eventname. Methods found, such as Application_Error, are then stored in a list of <a href="http://msdn.microsoft.com/en-us/library/system.reflection.methodinfo.aspx">MethodInfo</a>s and passed along to HttpApplication. Then, during HttpApplication initialization, events are bound to the methods within Global.asax.</p>
<p>That&#8217;s how Application_Error of Global.asax gets called even though the method isn&#8217;t overriding a base class implementation as is typical for the <a href="http://en.wikipedia.org/wiki/Template_method_pattern">template pattern</a>. That&#8217;s also why code within global.asax isn&#8217;t binary reusable across applications. An HttpModule, on the other hand, can be loaded into any number of applications.</p>
<p>In practice, implementing an HttpModule it a matter of creating a class that implements the <a href="http://msdn.microsoft.com/en-us/library/system.web.ihttpmodule.aspx">IHttpModule</a> interface:</p>
<pre class="prettyprint lang-cs">
public interface IHttpModule {
    void Init(HttpApplication context);
    void Dispose();
}
</pre>
<p>The crux of error handling with Asp.Net is the <a href="http://msdn.microsoft.com/en-us/library/system.web.httpapplication.error.aspx">Error</a> event of HttpApplication. The easiest way to hook up the event to a method is within the <a href="http://msdn.microsoft.com/en-us/library/system.web.ihttpmodule.init.aspx">Init</a> method of the class. In addition, we assign the application object to a field so that later we can access the most recently thrown exception through it:</p>
<pre class="prettyprint lang-cs">
public class EmailingExceptionModule : IHttpModule {
    private HttpApplication _application;

    public void Init(HttpApplication a) {
        _application = a;
        _application.Error += OnUnhaltedException;
    }

   public void Dispose() {}
   
   private void OnUnhaltedException(object sender, EventArgs e) {
       Exception ex = _application.Server.GetLastError().InnerException;
       // Implementation left out for brevity. Please download source 
   }
}
</pre>
<p>The OnUnhaltedException method is where to add code that collects information about the exception and the environment, and that composes and ships the email. Depending on the environment, you may find the need to include additional information in the email. Given the source code, adding to the email is a matter of adding key/value pairs in the form of labels and values to a dictionary. Each dictionary then gets rendered as a table of the key and value columns.</p>
<p>To have an Asp.Net application load the EmailingExceptionModule and to configure its email related settings, add the following nodes to the application&#8217;s web.config:</p>
<pre class="prettyprint lang-xml">
&lt;configuration&gt;
    &lt;appSettings&gt;
        &lt;add key="EmailingExceptionModule_SenderAddress" value="sender@domain.com"/&gt;
        &lt;add key="EmailingExceptionModule_ReceiverAddress" value="receiver@domain.com"/&gt;
        &lt;add key="EmailingExceptionModule_SmtpServer" value="mail.domain.com"/&gt;
        &lt;add key="EmailingExceptionModule_SubjectPrefix" value="MyApp: "/&gt;
    &lt;/appSettings&gt;
    &lt;system.web&gt;
        &lt;httpModules&gt;
            &lt;add name="EmailingExceptionModule" type="Holm.AspNet.EmailingExceptionModule,
                    EmailingExceptionModule, Version=1.0.0.0, Culture=neutral, 
                    PublicKeyToken=13806f613f05e959"/&gt;
        &lt;/httpModules&gt;
    &lt;/system.web&gt;                                    
&lt;/configuration&gt;
</pre>
<p>So what&#8217;s the user experience of unhalted exceptions? Outside the confines of the EmailingExceptionModule, there&#8217;s no indication that the application took note of what happened. Depending on the user&#8217;s profile, it might be helpful to prompt for additional information at the crash point. Or perhaps turn to the <a href="http://blogs.msdn.com/angus_logan/archive/2007/11/07/announcment-windows-live-messenger-im-control-presence-api-conversations-from-web-to-client-querying-presence.aspx">Windows Live Messenger IM Control &amp; Presence API</a> and have the user engage in an MSN conversation with a developer.</p>
<p>What&#8217;s the advantage of emailing developers unhalted exceptions over storing the information in the file system or a database? I believe in keeping things simple and practical, and handing off information to the file system or a database isn&#8217;t. Most likely the information will end up gathering virtual dust on some server. The email approach, on the other hand, is a proactive, visible, and efficient means to the end of rapidly course-correcting for wrong assumptions.</p>
<p><b>Update, Sep 15</b>: While you <a href="http://www.elumenotion.com/Blog/Lists/Posts/Post.aspx?ID=23">don&#8217;t need a PDB file to debug code</a> through Visual Studio (that&#8217;s what &lt;compilation debug=&#8221;true&#8221;&gt; in web.config is for), the PDB file is required for the <a href="http://timstall.dotnetdevelopersjournal.com/deploying_pdbs_to_get_the_exact_line_number_of_an_exception.htm">stack trace to contain line numbers</a>. Since the PDB file typically has to reside next to the corresponding DLL for the .Net runtime to pick it up, the PDB file may need to be deployed to the GAC along with the DLL. Refer to the first three paragraphs of the &#8220;Debugging assemblies that live in the GAC&#8221; section of <a href="http://blogs.msdn.com/markarend/archive/2008/09/09/debugging-web-parts-and-other-sharepoint-custom-code.aspx">this</a> post for how to GAC deploy PDB files.</p>
<p>For a centrally deployed Asp.Net application, it may be acceptable to ship and deploy the PDB file with the application. Keep in mind, though, that because the PDB file is a mapping of locations in the IL to the source file, having access to the PDB file makes it easier for someone to reverse engineer the code. It&#8217;s also possible to <a href="http://timstall.dotnetdevelopersjournal.com/getting_file_and_line_numbers_without_deploying_the_pdb_file.htm">get at line numbers without the PDB file</a> being deployed, but the approach is somewhat involved. Based on the mapping nature of the PDB file, the idea is to write out IL offsets as part of the exception and to post-process the offsets using a PDB file at a separate location.</p>
<p>Yet another alternative to shipping the PDB file is to setup a symbol server. With <a href="http://blogs.msdn.com/rmbyers/archive/2007/06/21/customizing-pdb-lookup-for-source-information-in-stacktrace.aspx">this</a> nifty piece of code, the <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.stacktrace.aspx">StackTrace</a> class loads the PDB file of the symbol server, adding line numbers to the stack trace.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2008/08/30/aspnet-error-handling-by-httpmodule/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to modify the enclosing tag of a web control</title>
		<link>http://www.bugfree.dk/blog/2008/07/30/how-to-modify-the-enclosing-tag-of-a-web-control/</link>
		<comments>http://www.bugfree.dk/blog/2008/07/30/how-to-modify-the-enclosing-tag-of-a-web-control/#comments</comments>
		<pubDate>Wed, 30 Jul 2008 20:45:47 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Asp.Net]]></category>
		<category><![CDATA[Html]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2008/07/30/how-to-modify-a-web-control%e2%80%99s-enclosing-tag/</guid>
		<description><![CDATA[In this post I&#8217;ll rework a piece of code that changes the enclosing tag of a web control from a span to a div. A substitution of particular value with SharePoint, where adding web controls is a common way to extend the out of box experience. With SharePoint, and Asp.Net in general, a page is [...]]]></description>
			<content:encoded><![CDATA[<p>In this post I&#8217;ll rework a piece of code that changes the enclosing tag of a web control from a <a href="http://webdesign.about.com/od/htmltags/a/aa011000a.htm">span to a div</a>. A substitution of particular value with SharePoint, where adding web controls is a common way to extend the out of box experience. With SharePoint, and Asp.Net in general, a page is typically composed of reusable controls, each responsible for rendering its part of the page.</p>
<p>To showcase anti-patterns of API usage, intermediate code is included, i.e., code that may render the correct tags, although not necessarily in the true spirit of the .Net framework.</p>
<p>To set the stage, imagine writing a web control that inherits from ASP.Net <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.webcontrol.aspx">WebControl</a>. The goal is then to modify the behavior of the control in such a way that it (1) encloses its content in a div tag and (2) adds a CSS class for styling, and (3) can be added to a page like so:</p>
<pre class="prettyprint lang-html">
&lt;MyControls:MyControl CssClass="myCssClass" runat="server" /&gt;
</pre>
<p>After making its way through the page rendering pipeline, the control tag gets transformed to:</p>
<pre class="prettyprint lang-html">
&lt;div class="myCssClass"&gt;
    Hello World
&lt;/div&gt;
</pre>
<p>Within the control, a straight-forward way of achieving the intended output may be to hand craft the html and render it in <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.webcontrol.rendercontents.aspx">RenderContents</a> of WebControl. It almost goes without saying that rendering html by hand is but only a starting point when working with .Net. The next progression from there may be to override <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.webcontrol.renderbegintag.aspx">RenderBeginTag</a> and <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.webcontrol.renderendtag.aspx">RenderEndTag</a> of WebControl:</p>
<pre class="prettyprint lang-cs">
// version 1
public class MyControl : WebControl {
    public override void RenderBeginTag(HtmlTextWriter w) {
        w.RenderBeginTag(string.Format("div class=\"{0}\"", CssClass));
    }
    
    public override void RenderEndTag(HtmlTextWriter w) {
        w.RenderEndTag();
    }

    protected override void RenderContents(HtmlTextWriter w) {
        w.Write("Hello World");
    }
}
</pre>
<p>Resulting in this piece of html:</p>
<pre class="prettyprint lang-html">
&lt;div class="myCssClass"&gt;
    Hello World
&lt;/div class="myCssClass"&gt;
</pre>
<p>Clearly, <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.webcontrol.renderbegintag.aspx">RenderBeginTag</a> and <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.webcontrol.renderendtag.aspx">RenderEndTag</a> of <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.htmltextwriter.aspx">HtmlTextWriter</a> don&#8217;t know how to separate tag from attribute. Nonetheless, the code reveals the stack based approach taken by the Render-pair of methods.</p>
<p>Gleaning over the documentation of HtmlTextWriter, however, I encountered the <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.htmltextwriter.addattribute.aspx">AddAttribute</a> method for setting attributes on a tag. Inside HtmlTextWriter, what AddAttribute does is add attributes and associated values to an array that gets rendered during the next call to RenderBeginTag. So besides introducing strongly typed attributes and tags, the next version contains a modified RenderBeginTag:</p>
<pre class="prettyprint lang-cs">
// version 2
public override void RenderBeginTag(HtmlTextWriter w) {
    w.AddAttribute(HtmlTextWriterAttribute.Class, CssClass);
    w.RenderBeginTag(HtmlTextWriterTag.Div);
}
</pre>
<p>Now the control renders as expected, although the code still has a certain bad smell to it. WebControl ought to know how to properly render its begin and end tag. After all it&#8217;s WebControl that exposes, among others, the <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.webcontrol.cssclass.aspx">CssClass</a> property. So taking another dive into the documentation, I found the virtual, read-only <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.webcontrol.tagkey.aspx">TagKey</a> property of WebControl. Strangely named as it may be, overriding TagKey makes WebControl call our override as it renders the control, adding in optional attributes, such as CssClass. Implementing the property also turns RenderBeginTag and RenderEndTag obsolete:</p>
<pre class="prettyprint lang-cs">
// version 3
protected override HtmlTextWriterTag TagKey {
    get {
        return HtmlTextWriterTag.Div;
    }
}
</pre>
<p>As an added bonus, changing the enclosing tag can also be done calling the WebControl&#8217;s constructor, passing in the desired tag:</p>
<pre class="prettyprint lang-cs">
// version  4
public class MyControl : WebControl {
    public MyControl() : base(HtmlTextWriterTag.Div) { }

    protected override void RenderContents(HtmlTextWriter w) {
        w.Write("Hello World");
    }
}
</pre>
<p>As it turns out, calling the constructor is how WebControl derived classes get to use span in the first place. The default WebControl constructor passes control onto another constructor that sets the value of what gets returned by the base class TagKey implementation. In essence, overriding TagKey makes it a player in the <a href="http://en.wikipedia.org/wiki/Template_method_pattern">template design pattern</a>:</p>
<pre class="prettyprint lang-cs">
// .Net framework code
protected WebControl() : this(HtmlTextWriterTag.Span) { }

public WebControl(HtmlTextWriterTag tag) {
    tagKey = tag;
}
</pre>
<p>Also worth noting is that for controls deriving from WebControl derived classes, such as <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.compositecontrol.aspx">CompositeControl</a>, the constructor cannot be used to set the enclosing tag. The constructor exposed by CompositeControl and friends doesn&#8217;t call up the constructor chain passing in the tag, making TagKey the choice to go.</p>
<p>Finally, deep down the inhertitance chain below WebControl lives <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.webparts.webpart.aspx">WebPart</a>, a type of control very popular with SharePoint. Interestingly enough, WebPart defaults to using div as its enclosing tag, because walking up the chain, we come across the constructor of <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.panel.aspx">Panel</a>:</p>
<pre class="prettyprint lang-cs">
// .Net framework code
public Panel() : base(HtmlTextWriterTag.Div) { }
</pre>
<p>So, using Panel provides another way to implement a web control that owns a distinct part of a page.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2008/07/30/how-to-modify-the-enclosing-tag-of-a-web-control/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Code based, dynamic CAML query composition</title>
		<link>http://www.bugfree.dk/blog/2008/07/03/code-based-dynamic-caml-query-composition/</link>
		<comments>http://www.bugfree.dk/blog/2008/07/03/code-based-dynamic-caml-query-composition/#comments</comments>
		<pubDate>Thu, 03 Jul 2008 18:50:52 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2008/07/03/code-based-dynamic-caml-query-generation/</guid>
		<description><![CDATA[Today I faced an interesting challenge while querying list items in SharePoint. On a page I have a control that displays list items based on the terms used to tag the page, i.e., the content type on which the page is based contains a multi-valued field that holds a subset of predefined tags. Similarly, for [...]]]></description>
			<content:encoded><![CDATA[<p>Today I faced an interesting challenge while querying list items in SharePoint. On a page I have a control that displays list items based on the terms used to tag the page, i.e., the content type on which the page is based contains a multi-valued field that holds a subset of predefined tags. Similarly, for items in a SharePoint list, each item is tagged using a subset of the same predefined tags. The responsibility of the control is then to (1) read the tags associated with the page and (2) query the tags of the list items in an OR-wise fashion. The (3) outcome is then displayed by the control as a set of context specific items.</p>
<p>To decide on the items to display, an initial approach might be to go through the list one item at a time, looking for matching tags. But <a href="http://technet.microsoft.com/en-us/library/cc262813.aspx">working with large lists in SharePoint</a> this approach is not recommended. Alternatively, the predicate against which each item in the list is evaluated could take on the form of a CAML query. Looking for items matching a single tag is then easily expressed:</p>
<pre class="prettyprint lang-xml">
&lt;Where&gt;
    &lt;Eq&gt;
        &lt;FieldRef Name='MyField' /&gt;
        &lt;Value Type='LookupMulti'&gt;tag1&lt;/Value&gt;
    &lt;/Eq&gt;
&lt;/Where&gt;
</pre>
<p>Next, consider a query with two tags OR&#8217;ed together. Although more verbose, the query is still fairly straightforward to compose on the fly:</p>
<pre class="prettyprint lang-xml">
&lt;Where&gt;
    &lt;Or&gt;
        &lt;Eq&gt;
            &lt;FieldRef Name='MyField' /&gt;
            &lt;Value Type='LookupMulti'&gt;tag1&lt;/Value&gt;
        &lt;/Eq&gt;
        &lt;Eq&gt;
            &lt;FieldRef Name='MyField' /&gt;
            &lt;Value Type='LookupMulti'&gt;tag2&lt;/Value&gt;
        &lt;/Eq&gt;
    &lt;/Or&gt;
&lt;/Where&gt;
</pre>
<p>However, for CAML queries where more than two tags are OR&#8217;ed together, the binary nature of the OR operator works against us. Where real programming languages have their parsers automatically transform an expression like (a || b || c) into ((a || b) || c), the CAML query parser applies no such transform &#8212; In a sense CAML is more like an XML serialized, abstract syntax tree than a query language intended for direct use:</p>
<pre class="prettyprint lang-xml">
&lt;Where&gt;
    &lt;Or&gt;
        &lt;Or&gt;
            &lt;Eq&gt;
                &lt;FieldRef Name='MyField' /&gt;
                &lt;Value Type='LookupMulti'&gt;tag1&lt;/Value&gt;
            &lt;/Eq&gt;
            &lt;Eq&gt;
                &lt;FieldRef Name='MyField' /&gt;
                &lt;Value Type='LookupMulti'&gt;tag2&lt;/Value&gt;
            &lt;/Eq&gt;
        &lt;/Or&gt;
        &lt;Eq&gt;
            &lt;FieldRef Name='MyField' /&gt;
            &lt;Value Type='LookupMulti'&gt;tag3&lt;/Value&gt;
        &lt;/Eq&gt;
    &lt;/Or&gt;
&lt;/Where&gt;
</pre>
<p>So how do we go about composing a query that OR together <em>n</em> tags (not to mention a mix of ORs and ANDs)? One approach might be using the <a href="http://www.u2u.info/SharePoint/U2U%20Community%20Tools/Forms/AllItems.aspx">U2U CAML Query Builder</a>. The tool delivers a UI for formulating queries, but also exposes its <a href="http://www.u2u.be/res/Article.aspx?ART=camlquerybuilderv2">CAML query builder API</a> as a .Net assembly. Unfortunately, documentation on how to use the builder is sparse. Nonetheless, I went for the case of composing a query that OR together three tags:</p>
<pre class="prettyprint lang-cs">
string ComposeCamlQuery() {
    Builder b = new Builder(CamlTypes.GetListItems);
    b.AddViewField("Title");
    b.AddViewField("MyField");

    bool addCombinerNode;
    foreach (string tag in new string[] { "tag1", "tag2", "tag3" })
        b.AddWhereField("MyField", tag, "LookupMulti", 
                        "Or", out addCombinerNode);
    return b.CamlDocument.InnerXml;
}
</pre>
<p>The outcome is a rather strange looking CAML query with extra &lt;And&gt;&lt;/And&gt; and missing &lt;Eq&gt;&lt;/Eq&gt; tags. Funny thing is that this type of the query can be correctly composed through the UI, so most likely I&#8217;m not using the API correctly:</p>
<pre class="prettyprint lang-xml">
&lt;Where&gt;
    &lt;And&gt;
        &lt;And&gt;
            &lt;Or&gt;
                &lt;FieldRef Name="MyField" /&gt; 
                &lt;Value Type="LookupMulti"&gt;tag1&lt;/Value&gt; 
            &lt;/Or&gt;
            &lt;Or&gt;
                &lt;FieldRef Name="MyField" /&gt; 
                &lt;Value Type="LookupMulti"&gt;tag2&lt;/Value&gt; 
            &lt;/Or&gt;
        &lt;/And&gt;
        &lt;Or&gt;
            &lt;FieldRef Name="MyField" /&gt; 
            &lt;Value Type="LookupMulti"&gt;tag3&lt;/Value&gt; 
        &lt;/Or&gt;
    &lt;/And&gt;
&lt;/Where&gt;
</pre>
<p>I eventually abandoned the idea of using the CAML Query Builder API. Instead, a colleague pointed me to <a href="http://www.sharepointblogs.com/tmt/archive/2007/08/30/dynamic-caml-query.aspx">Waldek Mastykarz&#8217;s post</a> on generating dynamic CAML queries. As long as all tags are to be either AND&#8217;ed or OR&#8217;ed together, Mastykarz provides an elegant solution, which I modified to be recursive, more generic, and read like an induction proof (at a negligible performance cost):</p>
<pre class="prettyprint lang-cs">
ComposeCamlQuery(new[] { "tag1", "tag2", "tag3" }, 
    "Or", 
    "&lt;Where&gt;{0}&lt;/Where&gt;",
    @"&lt;Eq&gt;
        &lt;FieldRef Name='MyField' /&gt;
        &lt;Value Type='LookupMulti'&gt;{0}&lt;/Value&gt;
     &lt;/Eq&gt;");

string ComposeCamlQuery(IList&lt;string&gt; ops, string relOp, 
                        string query, string leaf) {
    return ops.Count == 1
        ? string.Format(query, string.Format(leaf, ops[0]))
        : ComposeCamlQuery(ops.Skip(1).ToList(),
            relOp, 
            string.Format(query, 
                string.Format("&lt;{0}&gt;{1}{{0}}&lt;/{0}&gt;", 
                    relOp, 
                    string.Format(leaf, ops[0]))), 
                    leaf);
}
</pre>
<p>Obviously, more complex code could be written for a mix of AND&#8217;s and OR&#8217;s. Before doing so, however, you probably want to evaluate other approaches for filtering list items:</p>
<ol>
<li>Formulate a simpler, too general query and post-process the result
</li>
<li>Formulate smaller queries and optionally merge the results and do post-processing
</li>
<li>Use the SharePoint Search API 
</li>
</ol>
<p>I also considered such alternatives as <a href="http://www.codeplex.com/LINQtoSharePoint">Linq to SharePoint</a> or <a href="http://www.codeplex.com/camldotnet">Caml.net</a>, but although the first holds a lot of promise, it isn&#8217;t ready for prime time. As for the latter, its focus is more on composing type-safe queries than dynamic ones, so it&#8217;s more of a supplement to the first two alternatives.</p>
<p>As for SharePoint Search, the downside is that search has to be configured and that the list must have been indexed for the outcome to be accurate. Depending on the frequency with which the list is modified, the time between incremental crawls, and the context in which the results are displayed, the search approach may or may not be the solution you&#8217;re looking for.</p>
<p><b>Update, July 19</b>: Added recursive code solution.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2008/07/03/code-based-dynamic-caml-query-composition/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Prototyping LINQ using LINQPad</title>
		<link>http://www.bugfree.dk/blog/2008/06/29/prototyping-linq-using-linqpad/</link>
		<comments>http://www.bugfree.dk/blog/2008/06/29/prototyping-linq-using-linqpad/#comments</comments>
		<pubDate>Sun, 29 Jun 2008 12:44:00 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Tool]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2008/06/29/prototyping-linq-using-linqpad/</guid>
		<description><![CDATA[I&#8217;ve been doing some LINQ development lately. What I typically do is write a LINQ query within the production code and then attach a debugger to see what the query returns and perhaps what the underlying SQL statement looks like. For simple queries this technique is sufficient, but for more complex ones, several, cumbersome round-trips [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been doing some LINQ development lately. What I typically do is write a LINQ query within the production code and then attach a debugger to see what the query returns and perhaps what the underlying SQL statement looks like. For simple queries this technique is sufficient, but for more complex ones, several, cumbersome round-trips through the debugger are often necessary to get the query right.</p>
<p>Researching the issue I came across <a href="http://www.linqpad.net">LINQPad</a> (<a href="http://www.dimecasts.net/Casts/CastFeedDetails/22">see</a> LINQPad <a href="http://www.dimecasts.net/Casts/CastDetails/6">in</a> <a href="http://oreilly.com/pub/e/909">action</a>). The tool is a generic testbed for molding expressions or statements (LINQ being one such class) before embedding them into code. Also, because LINQPad is written by one of the authors of <a href="http://www.amazon.com/gp/product/0596527578?ie=UTF8&amp;tag=cinanu-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0596527578">C# in a Nutshell</a>, the tool comes with a lot of samples from the book.</p>
<p><a href="http://www.bugfree.dk/blog/wp-content/uploads/2008/06/LINQPadExample.png" target="_blank"><img src="http://www.bugfree.dk/blog/wp-content/uploads/2008/06/LINQPadExample.png" alt="" /></a></p>
<p>On the implementation side, LINQPad works by emitting MSIL behind the scenes, conceptually similar to the DataContext classes generated by Visual Studio when using the database design surface.</p>
<p>As an interesting side note, LINQPad can also show the query after it has been transformed into lambdas, anonymous types, and the like:</p>
<pre class="prettyprint lang-cs">
Users
    .Join (
        Macs,
        u => u.UserId,
        m => m.UserId,
            (u, m) =>
                 new
                 {
                     u = u,
                     m = m
                 }
    )
    .Where (temp0 => (temp0.u.Created < DateTime.Now.AddHours (-24)))
    .Select (
        temp0 =>
            new
            {
                UserId = temp0.u.UserId,
                UserCreated = temp0.u.Created,
                Mac = temp0.m.Mac,
                Active = temp0.m.Active
            }
    )
    .Take (15)
</pre>
<p>Keep in mind how the .Net 3.5 framework and the .Net 3.5 compiler play together to ultimately transform the LINQ query into MSIL. What the framework does is transform the LINQ query into the above expression by applying a transform to the abstract syntax tree of the LINQ query. The .Net 3.5 compiler then transforms the lambdas, the anonymous types, and the like into .Net 2.0 MSIL (there&#8217;s no such thing as a .Net 3.5 CLR. For an overview of how the various versions of the framework, the compiler, and the CLR relate to each other, see Scott Hanselman&#8217;s <a href="http://www.hanselman.com/blog/HowToSetAnIISApplicationOrAppPoolToUseASPNET35RatherThan20.aspx">blog entry</a>).</p>
<p>But back to LINQPad. The only downside that I&#8217;ve encountered is that there&#8217;s no IntelliSense support in the current 1.24 release. However, even without IntelliSense support LINQPad is still a very valuable tool.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2008/06/29/prototyping-linq-using-linqpad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My SharePoint developer’s companion</title>
		<link>http://www.bugfree.dk/blog/2008/05/19/my-sharepoint-developer%e2%80%99s-companion/</link>
		<comments>http://www.bugfree.dk/blog/2008/05/19/my-sharepoint-developer%e2%80%99s-companion/#comments</comments>
		<pubDate>Mon, 19 May 2008 19:17:04 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Book]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2008/05/18/my-sharepoint-developer%e2%80%99s-companion/</guid>
		<description><![CDATA[As part of my preparation for the SharePoint configuration exams (70-630 and 70-731), I just finished working my way through Bill English&#8216;s SharePoint Administrator&#8217;s Companion. This book obviously targets SharePoint administrators. But after finishing the book, I believe it&#8217;s a must read for SharePoint developers as well. As such, I&#8217;d argue that a developer should [...]]]></description>
			<content:encoded><![CDATA[<p>As part of my preparation for the SharePoint configuration exams (<a href="http://www.microsoft.com/learning/exams/70-630.mspx">70-630</a> and <a href="http://www.microsoft.com/learning/exams/70-631.mspx">70-731</a>), I just finished working my way through <a href="http://mindsharpblogs.com/Bill/">Bill English</a>&#8216;s <a href="http://www.amazon.com/Microsoft%C2%AE-Office-SharePoint%C2%AE-Administrators-Companion/dp/0735622825/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1211133765&amp;sr=8-1">SharePoint Administrator&#8217;s Companion</a>.
</p>
<p>This book obviously targets SharePoint administrators. But after finishing the book, I believe it&#8217;s a must read for SharePoint developers as well. As such, I&#8217;d argue that a developer should know what and how SharePoint is capable of, starting with the point and click approach of this book and then progressing towards code. And by capable I&#8217;m referring to all parts of SharePoint, including the Central Administration and the Shared Services Provider.
</p>
<p>Knowing the capabilities of point and click comes in handy when discussing requirements. It often lays the groundwork for a prototype and helps you figure out where to extend SharePoint to fulfill the business needs. In addition, knowing what SharePoint can do on a general level makes estimates more reliable. Learning about administrative tasks also has the added benefit of establishing a common terminology between a developer and an administrator.
</p>
<p>All in all, the SharePoint Administrator&#8217;s Companion does a solid job of providing an overview of the capabilities of the SharePoint platform, demonstrated mostly through point and click. I&#8217;d therefore advocate that any developer should know the content of this book by heart, and use it as a starting point before moving on to more code-centric books such as the <a href="http://www.amazon.com/Microsoft-Windows-SharePoint-Services-Developer/dp/0735623201/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1211147074&amp;sr=8-1">Inside Microsoft Windows SharePoint Services 3.0</a> and the <a href="http://www.amazon.com/Inside-Microsoft-Office-SharePoint-Server/dp/0735623686/ref=bxgy_cc_b_img_a">Inside Microsoft Office SharePoint Service 2007</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2008/05/19/my-sharepoint-developer%e2%80%99s-companion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>User space traffic shaping with Ruby</title>
		<link>http://www.bugfree.dk/blog/2008/04/12/user-space-traffic-shaping-with-ruby/</link>
		<comments>http://www.bugfree.dk/blog/2008/04/12/user-space-traffic-shaping-with-ruby/#comments</comments>
		<pubDate>Sat, 12 Apr 2008 16:13:39 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Networking]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2008/04/12/user-space-traffic-shaping-with-ruby/</guid>
		<description><![CDATA[Download Netwatch-1.0.zip. In my Kernel space traffic shaping with Linux post, I came to the conclusion that none of the traffic shaping algorithms within the Linux kernel was suitable for my needs. The effects of running the traffic shaping algorithms were too hard to quantify and coming up with the right set of parameters to [...]]]></description>
			<content:encoded><![CDATA[<p>Download <a href="/software/Netwatch-1.0.zip">Netwatch-1.0.zip</a>.</p>
<p>In my <a href="2007/11/18/kernel-space-traffic-shaping-with-linux">Kernel space traffic shaping with Linux</a> post, I came to the conclusion that none of the traffic shaping algorithms within the Linux kernel was suitable for my needs. The effects of running the traffic shaping algorithms were too hard to quantify and coming up with the right set of parameters to go with each algorithm was challenging.</p>
<p>So I decided to come up with my own shaping algorithm, running in user space because it&#8217;s simpler working from there. I also wanted to use Ruby to learn the language and because of Ruby&#8217;s good properties as an integration platform. Lastly, I wanted the shaper to perform deferred shaping based on the traffic patterns observed over a period of hours or days rather than the more or less immediate shaping carried out by the kernel-based algorithms.</p>
<p>Before getting into the details, I should mention that these concepts have been successfully applied to shaping traffic on our 100/100 mbps Internet connection, shared by some 330 apartments, for well over a year. We&#8217;re no longer experiencing issues with network congestion and now that we use a payload agnostic shaper, we no longer have to combat the ever more sophisticated attempts of P2P software to camouflage its traffic.</p>
<h4>Architectural overview</h4>
<p>At an overview level the shaper is composed into a number of subsystems. At the top are the WRR scheduler, the ARP cache, and the RRD database system that retrieve and store metadata information about computers and their traffic.</p>
<p><img src="http://www.bugfree.dk/blog/wp-content/uploads/2008/04/shaperoverview.png" alt="shaperoverview.png" /></p>
<p>Based on input from these subsystems, the shaper&#8217;s decision engine evaluates each computer&#8217;s bandwidth usage against a set of rules. Should at least one rule be violated, e.g., too much traffic over some defined period of time, the shaper calls out to another subsystem that determines how to handle the violation. In this case Netfilter is called upon to take action, blocking the computer from accessing the Internet and redirecting it to an information page.</p>
<h4>Weighted Round Robin scheduler</h4>
<p>Within the shaper, kernel and user space form a symbiosis through the WRR scheduler. As part of WRR&#8217;s inner workings, the scheduler counts the bytes transmitted on a per IP basis. So although we don&#8217;t use WRR for shaping, per say, we do use it to track the byte counters of each computer.</p>
<p>Getting WRR to reveal this information is done through the tc (for traffic control) command. As outlined in the <a href="2007/11/18/kernel-space-traffic-shaping-with-linux">Kernel space traffic shaping with Linux</a> post, only outgoing traffic can be shaped by WRR (any algorithm really). Hence, tc is called once for eth0 and once for eth1, and parsing the result, we know have much traffic has entered and exited each computer between this and the previous call to tc.</p>
<p>For each computer the output has the form below. Of particular interest are the address and the bytes fields:</p>
<pre>
% tc class show dev eth0
class wrr 8001:1fb parent 8001:
   (address: 192.168.1.231)
   (total weight: 0.872749) (current position: 4) (counters: 1 2 : 3 4)
   Pars 1: (weight 0.872749) (decr: 1e-10) (incr: 7.5e-11) (min: 0.1) (max: 1)
   Pars 2: (weight 1) (decr: 0) (incr: 0) (min: 1) (max: 1)
   bytes: 4546184) (packets: 55373)
   ...
</pre>
<p>The address is dynamically assigned through DHCP and is therefore subject to change. Also, the byte counters aren&#8217;t retained across restarts, so we need to draw on additional subsystems to align the WRR output with a computer&#8217;s unique identity across time.</p>
<h4>Address Resolution Protocol</h4>
<p>In a DHCP based environment the IP address of a machine may change over time. So to ensure that traffic is always attributed to the correct physical machine, the WRR byte counters aren&#8217;t tied directly to the IP address when stored. Instead, we use the ARP cache to look up the corresponding MAC address, which is assumed to be static.</p>
<p>This lookup is done by maintaining an in-memory set of IP/MAC mappings, populated by parsing the output of the ip command:</p>
<pre>
% ip neigh
192.168.1.231 dev eth1 lladdr 00:50:8d:68:50:75 REACHABLE
192.168.3.117 dev eth1 lladdr 00:11:d8:8f:0e:3b REACHABLE
...
</pre>
<p>Thus, combining WRR with ARP, the shaper is able to associate byte counters with the MAC addresses of LAN-connected computers. Restarting the machine, the shaper, or Netfilter, however, will still cause traffic shaping data accumulated over time to be lost.</p>
<h4>Round Robin Databases</h4>
<p>We could&#8217;ve opted for persistence to a text file, a hierarchical XML structure, or a relational database, but <a href="http://en.wikipedia.org/wiki/Time_series">time series</a> data doesn&#8217;t lend itself well to these traditional approaches &#8212; at least not without preprocessing. Because with time series data, such as the 32 bit integer byte counters for each computer, counter-wrap is a frequent event (occurs every 4GB of transferred data). And restarting the machine, the shaper, or Netfilter is also a common event that&#8217;ll most likely cause an outlier to be recorded because all counters are reset.</p>
<p>Logic for making sure these events doesn&#8217;t pollute our database with erroneous measurements are part of the defining characteristics of a time series database system. In addition, querying data, such as summing within a period of time and making sure the sum isn&#8217;t affected by the above events, is what a time series database is good at.</p>
<p>On Linux-based based systems, <a href="http://tobi.oetiker.ch/">Tobias Oetiker&#8217;s</a> <a href="http://oss.oetiker.ch/rrdtool/">Round Robin Database tools</a> are the de facto tools for storing, querying, and graphing time series data, and therefore the ones used by the shaper.</p>
<p>The idea is that, using the RRD tools, each computer gets its own database, named after the corresponding MAC address, describing its traffic over time. So querying the database of each computer can tell us how much data was transferred and received over some period of time. Using the RRD tools for this task eliminating the need on our behalf to deal with outliers, missing values, counter-wraps, and so forth. All the shaper has to do is record the value of the counters at regular intervals and RRD makes sure data is consistent within the database.</p>
<h4>Decision engine</h4>
<p>To put the shaper online, it&#8217;s run from a Bash script containing an infinite loop that (1) reads and parses the WRR output, (2) reads and parses the ARP cache entries, (3) writes the byte counters to the RRD databases, (4) uses the RRD querying tool to sum the data based on the rules specified, possibly causing a violation event to fire, and finally (5) goto sleep for some period of time before starting all over.</p>
<p>Whenever a rule is violated, the action taken may be whatever can be expressed though Ruby code or through a callout. This may involve sending an email to the network administrator or disabling Internet access for the computer in question.</p>
<p>Within our configuration, we defined a set of rules that state that within a four hour sliding window a computer is allowed to upload no more than 5GB and download 10GB of data. Similarly, during a seven day sliding window, a computer is allowed to upload no more than 30GB and download 60GB of data (the exact quotas and periods obviously depend on the network capacity, users online, their usage patterns, and so forth).</p>
<p>Upon violation of a rule, we employ Netfilter to redirect a computer to an information page stating that the computer is blocked from accessing the Internet in conjunction with the sum of the four hour and seven day totals.</p>
<h4>Conclusion</h4>
<p>Observing the proof of concept shaper in action, the biggest problem seems to be that a few users modify their MAC address to get a bigger piece of the bandwidth pie. If we wanted, though, changing the MAC can be counteracted by introducing another layer, and instead tie traffic to the port on the switch to which the computer is connected.</p>
<p>As far as the available source code goes, it should probably only be used as a starting point for building your own system.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2008/04/12/user-space-traffic-shaping-with-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>70-541: WSS 3.0, application development</title>
		<link>http://www.bugfree.dk/blog/2007/12/21/70-541-wss-30-application-development/</link>
		<comments>http://www.bugfree.dk/blog/2007/12/21/70-541-wss-30-application-development/#comments</comments>
		<pubDate>Fri, 21 Dec 2007 16:23:59 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[SharePoint]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2007/12/21/70-541-wss-30-application-development/</guid>
		<description><![CDATA[Today I passed my first Microsoft exam ever, the 70-541: Microsoft Windows SharePoint Services 3.0, Application Development. In preparation for the exam I found the Inside Microsoft Windows SharePoint Services 3.0 book and the Windows SharePoint Services 3.0 SDK to be the best study materials. In addition, I looked to others for tips and tricks. [...]]]></description>
			<content:encoded><![CDATA[<p>Today I passed my first Microsoft exam ever, the <a href="http://www.microsoft.com/learning/exams/70-541.mspx">70-541</a>: Microsoft Windows SharePoint Services 3.0, Application Development.</p>
<p>In preparation for the exam I found the <a href="http://www.amazon.com/Microsoft-Windows-SharePoint-Services-Developer/dp/0735623201/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1198497448&#038;sr=8-1">Inside Microsoft Windows SharePoint Services 3.0</a> book and the <a href="http://msdn2.microsoft.com/en-us/library/ms472057.aspx">Windows SharePoint Services 3.0 SDK</a> to be the best study materials. In addition, I looked to <a href="http://www.sharepoint-tips.com/2007/01/sharepoint-2007-beta-exams-tips.html">others</a> for tips and tricks. </p>
<p>I found the SDK to be supprisingly thorough, compared to the book, which doesn&#8217;t cover the entire curriculum. The book alone does get one enough points to pass the exam, though.</p>
<p>Overall the exam questions could benefit from a review for verbosity and clear wording. Also, one question was about the <a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.page.registerhiddenfield(VS.80).aspx">RegisterHiddenField</a> method and the <a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.page.registerhiddenfield(VS.80).aspx">RequestFromAdminPort</a> property, which MSDN marks as obsolete. Another question was about adding a column to a content type and pushing the change to a list based on the content type. On that question I could&#8217;ve sworn that two of the possible answers were correct.</p>
<p>Nonetheless, learning SharePoint with a specific goal and deadline in mind serves as a good motivator.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2007/12/21/70-541-wss-30-application-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Kernel space traffic shaping with Linux</title>
		<link>http://www.bugfree.dk/blog/2007/11/18/kernel-space-traffic-shaping-with-linux/</link>
		<comments>http://www.bugfree.dk/blog/2007/11/18/kernel-space-traffic-shaping-with-linux/#comments</comments>
		<pubDate>Sun, 18 Nov 2007 18:58:09 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Networking]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2008/10/26/kernel-space-traffic-shaping-with-linux/</guid>
		<description><![CDATA[Where I live, we have a Linux box sitting between the Internet and the local area network, providing Internet access to some 330 apartments. With this many users, and even more computers, access to the Internet through our 30/30 mbit/s connection quickly turned bandwidth into a scarce resource. Not so much because users surf the [...]]]></description>
			<content:encoded><![CDATA[<p>Where I live, we have a Linux box sitting between the Internet and the local area network, providing Internet access to some 330 apartments.</p>
<p>With this many users, and even more computers, access to the Internet through our 30/30 mbit/s connection quickly turned bandwidth into a scarce resource. Not so much because users surf the web or check their email, but because P2P clients are in common use. And with this kind of software no amount of bandwidth can really satisfy its need, calling for a way to distribute bandwidth between users or computers that is fairer than the first come, first served one. </p>
<p>For some time we counteracted the effect of P2P clients on our bandwidth by using <a href="http://www.ipp2p.org">ipp2p</a> on top of <a href="http://www.netfilter.org">Netfilter</a>. Unfortunately, popular P2P clients are able to sneak below the ipp2p radar using HTTP as their transport and obfuscating their traffic. </p>
<p>Thus, we turned our attention to the <a href="http://www.linux.org/docs/ldp/howto/Adv-Routing-HOWTO/lartc.qdisc.html">queuing disciplines</a> of the <a href="http://www.linux.org/docs/ldp/howto/Adv-Routing-HOWTO/">Linux Advanced Routing &#038; Traffic Control Howto</a>. The idea behind a queuing discipline, or qdisc for short, is to apply some processing on the queue of packets in the kernel waiting to be sent (either from the network interface on the local area network side to the network interface on the Internet side or vice versa). Generally speaking, processing involves moving around packets in the sent queue to allow for some packets to go out on the wire before others, based on the algorithm of the qdisc. </p>
<p>The net effect is that users whose packets get moved to the front of the queue will experience a lower latency, higher bandwidth connection. Conversely, owners of packets in the back of the queue may have their packets delayed to the point where their <a href="http://en.wikipedia.org/wiki/Transmission_Control_Protocol">TCP/IP</a> stack is forced to decrease the speed with which data is sent, simply because the receiver reports that not all packets arrived on schedule.</p>
<p>Experimenting with the simpler qdiscs, such as <a href="http://www.linux.org/docs/ldp/howto/Adv-Routing-HOWTO/lartc.qdisc.classless.html#AEN495">Token Bucket Filter</a href> (TBF), <a href="http://www.linux.org/docs/ldp/howto/Adv-Routing-HOWTO/lartc.qdisc.classless.html#LARTC.SFQ">Stochastic Fairness Queuing</a> (SFQ), and <a href="http://www.linux.org/docs/ldp/howto/Adv-Routing-HOWTO/lartc.qdisc.classful.html#AEN735">Class Based Queuing</a> (CBQ), we found quantifying their effects on the bandwidth consumption hard. Partly because these qdiscs aren&#8217;t intended for shaping individual computers, but rather a group of computers sharing some network usage characteristic. Sure, SFQ shapes each connection, but a computer may have any number of open connections, so shaping each connection independently is no good at limiting P2P traffic.</p>
<p>Therefore, we turned our attention to the <a href="http://www.linux.org/docs/ldp/howto/Adv-Routing-HOWTO/lartc.adv-qdisc.wrr.html">Weighted Round Robin</a> qdisc (which requires kernel patching and compilation). As opposed to the other qdiscs, WRR has the ability to shape traffic from individual computers by creating a CBQ for each one. Applying WRR to the sent queue of each network interface, WRR will assign an inbound and an outbound weight to each computer. Furthermore, the weight is adjusted as a function of the amount of data transmitted within some quantum of time. Then, when the demand for bandwidth exceeds what&#8217;s available, the computer with the highest weight gets to go first. </p>
<p>On paper this is a great idea, but like with the other qdiscs, we found it hard to balance the various parameters and measure the net effect.</p>
<p>In conclusion, a great deal of time went into experimenting with the various qdiscs, even in combination with ipp2p. But eventually we decided that none of the qdiscs were up to solving our network congestion problem. The research effort wasn&#8217;t all in vain, though, because we found that WRR provides us with a cost effective way of counting incoming and outgoing bytes on a computer by computer basis. Thus, in a way all this helped crystallize the idea of building a payload agnostic, <a href="http://www.bugfree.dk/blog/2008/04/12/user-space-traffic-shaping-with-ruby/">user space traffic shaper in Ruby</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2007/11/18/kernel-space-traffic-shaping-with-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Purging inactive users from e107</title>
		<link>http://www.bugfree.dk/blog/2007/10/29/purging-inactive-users-from-e107/</link>
		<comments>http://www.bugfree.dk/blog/2007/10/29/purging-inactive-users-from-e107/#comments</comments>
		<pubDate>Mon, 29 Oct 2007 21:35:02 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Tool]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2007/10/29/purging-inactive-users-from-e107/</guid>
		<description><![CDATA[Download E107InactiveUserPurger-1.0.zip. As part of my use of the e107 open source contents management system, I want to purge the user accounts that’ve not logged in recently. This is something not supported out of the box, but by going through MySQL and accessing the e107_user table directly, the date of last login is accessible to [...]]]></description>
			<content:encoded><![CDATA[<p>Download <a href="/software/E107InactiveUserPurger-1.0.zip">E107InactiveUserPurger-1.0.zip</a>.</p>
<p>As part of my use of the <a href="http://e107.org/news.php">e107</a> open source contents management system, I want to purge the user accounts that’ve not logged in recently. This is something not supported out of the box, but by going through MySQL and accessing the e107_user table directly, the date of last login is accessible to anyone.</p>
<p>I’ve therefore written a small command-line tool in C# that makes use of the e107_user information to sent inactive users a warning email that their accounts are about to be purged (or whatever you want to happen).</p>
<p>The tool may be run in one of two modes, determined by a command-line switch.<br />
</p>
<ul>
<li>GenerateWarningMails: emails users that have not logged in during the last WarningPeriod days.</li>
<li>GeneratePurgeMailForAdministrator: emails site administrator a list of users that have not logged in during the last PurgePeriod days.</li>
</ul>
<p>Before running E107InactiveUserPurger, make sure to go to the Debug directory and adjust the settings in E107InactiveUserPurger.exe.xml to match your environment. You might also want to adjust the WarningMailTemplate.txt, which serves as a template for generating the body of warning emails. </p>
<p>Note that within the WarningMailTemplate.txt file, you&#8217;re free to add placeholders for fields within the e107_user table. Thus, if you want to include the login name of a user within the warning email, you’d write $user_loginname$.</p>
<p>Now you might run E107InactiveUserPurger as a scheduled task. Keep in mind, though, that the tool doesn’t actually purge the user accounts. Therefore, running it too often with the GenerateWarningMails switch may result in users receiving more than one warning email.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2007/10/29/purging-inactive-users-from-e107/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Good SharePoint development practices</title>
		<link>http://www.bugfree.dk/blog/2007/07/29/good-sharepoint-development-practices/</link>
		<comments>http://www.bugfree.dk/blog/2007/07/29/good-sharepoint-development-practices/#comments</comments>
		<pubDate>Sun, 29 Jul 2007 14:25:23 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SharePoint]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2007/07/29/future-sharepoint-development-environment/</guid>
		<description><![CDATA[Lately I&#8217;ve been working on creating a portal with Windows SharePoint Services 2007 (WSS 3.0) for a large customer. The easy and intuitive way to create such a portal is to configure it through the web browser and using SharePoint Designer (a renamed and spruced up FrontPage) for everything not code-related. Unfortunately, using the web [...]]]></description>
			<content:encoded><![CDATA[<p>Lately I&#8217;ve been working on creating a portal with <a href="http://www.microsoft.com/sharepoint/default.mspx">Windows SharePoint Services 2007</a> (WSS 3.0) for a large customer. The easy and intuitive way to create such a portal is to configure it through the web browser and using SharePoint Designer (a renamed and spruced up FrontPage) for everything not code-related. </p>
<p>Unfortunately, using the web interface and SharePoint Designer doesn&#8217;t scale well. With the drag and drop tools there is just no real support for deploying your portal to another server, and hence to unify the individual contributions of team members.</p>
<p>Therefore, the <a href="http://msdn2.microsoft.com/en-us/library/bb530302.aspx">current</a> way to go for any real SharePoint development is to work with the 12 Hive directly. Named after Office 12 (Office 2007), the 12 Hive is a hierarchy of xml files residing in &#8220;Program Files\Common Files\Microsoft Shared\web server extensions\12&#8243; that controls almost everything about how SharePoint and your portal behaves.</p>
<p>Using Visual Studio (VS), you’d create a 12 Hive parallel file hierarchy of new folders and files and work within VS as usual. Like with any other project, you&#8217;d use version control, <a href="2006/11/19/cruisecontrolnet-and-build-queues/">continuous integration</a>, and so on, on xml and .Net code. With VS, deployment (to your development box) would then involve checking out xml and code from source control and compiling the code. </p>
<p>Then, using a build script, you&#8217;d xcopy the xml and binary into the 12 Hive and GAC, respectively, and possibly run various stsadm commands to activate your features. Alternatively, you&#8217;d create a SharePoint solution package that pretty much does the same thing when invoked by SharePoint.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2007/07/29/good-sharepoint-development-practices/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Real time physics in games</title>
		<link>http://www.bugfree.dk/blog/2007/06/14/real-time-physics-in-games/</link>
		<comments>http://www.bugfree.dk/blog/2007/06/14/real-time-physics-in-games/#comments</comments>
		<pubDate>Thu, 14 Jun 2007 15:19:22 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Gaming]]></category>
		<category><![CDATA[Math]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2007/06/14/real-time-physics-in-games/</guid>
		<description><![CDATA[I was watching the interview with Brian Beckman on real time physics simulation in games over at Channel 9. In the video Brian explains the challenges involved in creating an accurate, real time physics model in games, specifically for flight simulators and race car games. Although the math is quite involved, Brian does a superb [...]]]></description>
			<content:encoded><![CDATA[<p>I was watching the <a href="http://channel9.msdn.com/Showpost.aspx?postid=314874">interview</a> with <a href="http://weblogs.asp.net/brianbec/articles/440296.aspx">Brian Beckman</a> on real time physics simulation in games over at <a href="http://channel9.msdn.com">Channel 9</a>. In the video Brian explains the challenges involved in creating an accurate, real time physics model in games, specifically for flight simulators and race car games.  Although the math is quite involved, Brian does a superb job of transforming the material into something digestible and fascinating.</p>
<p>In summary, <a href="http://en.wikipedia.org/wiki/Moore%27s_law">Moore’s law</a> enables game designers to use real time physics in games to accurately simulate something as complicated as a race car. Simulating an airplane has been possible for well over twenty years, but that&#8217;s only because the airplane moves smoothly through the air and is composed of simple components, such as a wing and a fuselage, which translates into few and simple equations to solve for each frame. </p>
<p>A race car, on the other hand, has four wheels touching the ground and connected to the car through some kind of suspension. Hence each wheel has to be accounted for independently. In addition, the clutch, gear box, and aerodynamics of the car, not to mention the terrain, have a profound impact on the physics model, calling for a more involved set of <a href="http://phors.locost7.info ">equations</a> to solve.</p>
<p>As computes have become fast enough to match the frame rate given this challenging set of equations, race car games have become as realistic as flight simulators. With more horsepower, however, comes a need for even more realism. So even though computers become faster/fatter at an exponential rate, simplifying the model is, and probably always will be, worth striving for.</p>
<p>This is where <a href="http://rigsofrods.blogspot.com">Rigs of Rods</a> enters the video at time index 00:56:10. The game takes the opposite approach of using advanced equations, with the risk of introducing divergence or singularities into the model when, say, the denominator of a fraction approaches zero. Instead the game uses simple/simpler equations, such as <a href="http://en.wikipedia.org/wiki/Harmonic_oscillator">harmonic oscillators</a>, as a mean of modeling airplanes, cars, trucks, etc. using sticks and stones (or rigs of rods, hence the name).<br />
<object width="425" height="350"><param name="movie" value="http://www.youtube.com/v/TR9jqGv05H4"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/TR9jqGv05H4" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"></embed></object><br />
<br />
The sticks and stones approach works by assigning mass to the stones and connecting them using the sticks, and then adding textures on top. This more general, but also more computationally intensive, model creates a very realistic experience.</p>
<p>I’ve been playing the game for a couple of days now, and although it initially appears simple it’s surprisingly entertaining. A lot of time goes into exploring the scenery using the various modes of transportation.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2007/06/14/real-time-physics-in-games/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Alerts</title>
		<link>http://www.bugfree.dk/blog/2007/05/25/google-alerts/</link>
		<comments>http://www.bugfree.dk/blog/2007/05/25/google-alerts/#comments</comments>
		<pubDate>Fri, 25 May 2007 09:09:27 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Tool]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2007/05/25/google-alerts/</guid>
		<description><![CDATA[I just learned about Google Alerts. It&#8217;s a simple service where you enter keywords for Google to search. Then Google will monitor the search results and send you an email whenever new hits appear in the search result. Time will tell if it&#8217;s truly useful to have your own personal intelligence service at your hands. [...]]]></description>
			<content:encoded><![CDATA[<p>I just learned about <a href="http://www.google.com/alerts">Google Alerts</a>.</p>
<p>It&#8217;s a simple service where you enter keywords for Google to search. Then Google will monitor the search results and send you an email whenever new hits appear in the search result.</p>
<p>Time will tell if it&#8217;s truly useful to have your own personal intelligence service at your hands. So far I receive alerts about the company I work for, the region where I live, myself, and so on.</p>
<p><b>Update, May 29</b>: In my experience there are too many ads at the top of each email I receive. Also, Google sends me a daily email for each alert even though there are no new search results. </p>
<p>Thus,  bulking alerts would be a nice option. Or perhaps you could write something better by coding against the <a href="http://code.google.com/">Google APIs</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2007/05/25/google-alerts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tapping the power of PlayStation 3</title>
		<link>http://www.bugfree.dk/blog/2007/04/15/tapping-the-power-of-playstation-3/</link>
		<comments>http://www.bugfree.dk/blog/2007/04/15/tapping-the-power-of-playstation-3/#comments</comments>
		<pubDate>Sun, 15 Apr 2007 21:21:14 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2007/04/15/taming-the-power-of-playstation-3/</guid>
		<description><![CDATA[I recently had the fortunate opportunity to spend a few days with the PlayStation 3 (PS3). Its hardware configuration is truly amazing: a PowerPC based Cell processor with eight cores, although only seven is in active use to decrease the number of faulty units coming off the assembly line, running at 3.2 GHz and an [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had the fortunate opportunity to spend a few days with the PlayStation 3 (PS3). Its <a href="http://en.wikipedia.org/wiki/Playstation_3#Hardware">hardware configuration</a> is truly amazing: a PowerPC based Cell processor with eight cores, although only seven is in active use to decrease the number of faulty units coming off the assembly line, running at 3.2 GHz and an NVidia based graphics card.</p>
<p>Of course, all that power is there to be tapped primarily by games. However, with the firmware upgrade to version 1.6, Sony added a menu item for easily joining the <a href="http://folding.stanford.edu">Folding@home</a> distributed computing project: a project that does molecular simulation across hundreds of thousands of computers in the hope of identifying the underlying causes of Alzheimer&#8217;s, Parkinson&#8217;s, and cancer, etc. </p>
<p>Assuming the PS3 has network access (it comes with build-in Wi-Fi, by the way), selecting the menu item causes the console to go <a href="http://folding.stanford.edu/download.html">download</a> the Folding@home client and start processing. That way, when you&#8217;re not using the console for gaming, you can donate the spare cycles to something useful. At least to me, participating in the Folding@home project is more meaningful than, say, aiding the <a href="http://setiathome.berkeley.edu/">search for extraterrestrial intelligence</a>.</p>
<p>According to the Folding@home <a href="http://folding.stanford.edu/FAQ-PS3.html">FAQ</a>, the PS3 has been benchmarked at 10x the speed of a regular computer. The downside, however, is that &#8220;&#8230; the PS3 [client] takes the middle ground between GPU&#8217;s (extreme speed, but at limited types of WU&#8217;s [work units]) and CPU&#8217;s (less speed, but more flexibility in types of WU&#8217;s)&#8221;. Perhaps because the processor &#8220;&#8230; lack most of the general-purpose features that you normally expect in a processor&#8221;, as described <a href="http://www-128.ibm.com/developerworks/power/library/pa-linuxps3-1/">here</a>.</p>
<p>Another interesting aspect of the PS3 is the support for running <a href="http://en.wikipedia.org/wiki/PlayStation_3_Linux">other</a> operating systems, particularly Linux. From the menu, you can repartition the standard 60 GB SATA hard disk. The operating system of the PS3 is run from internal memory for faster boot times and it&#8217;s only using the disk for storing game state and other data not vital for booting the PS3 kernel. Thus, installing Linux, you shouldn&#8217;t have to worry about accidentally wiping out the factory operating system.</p>
<p>Installing Linux on the thing is still something left to try. But it seems like buying a USB  mouse and keyboard could transform the PS3 into a regular desktop computer, in turn making the price more digestible.</p>
<p><b>Update, September</b>: I successfully <a href="http://mirror.anl.gov/yellowdog/iso/">downloaded</a> and installed <a href="http://www.terrasoftsolutions.com/products/ydl/">Yellow Dog Linux</a> on a PS3. Following the <a href="http://www.terrasoftsolutions.com/support/installation/ydl5.0.2_ps3_guide.pdf">installation guidelines</a> it went surprisingly smooth. After installing, you can add the Fedora software archives to the list of possible installation sources for Yum. This&#8217;ll make even more software available without having to compile it yourself. Personally, the most used application is the <a href="http://www.videolan.org/vlc/">VLC media player</a>, which, at a mare double click, is able to play just about any video format in full screen mode. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2007/04/15/tapping-the-power-of-playstation-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Increasing VMWare disk size</title>
		<link>http://www.bugfree.dk/blog/2007/03/22/increasing-vmware-disk-size/</link>
		<comments>http://www.bugfree.dk/blog/2007/03/22/increasing-vmware-disk-size/#comments</comments>
		<pubDate>Thu, 22 Mar 2007 19:47:21 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Windows]]></category>
		<category><![CDATA[Tip]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2007/03/22/increasing-vmware-disk-size/</guid>
		<description><![CDATA[I recently increased my VMWare disk image size from 10 to 15 GB. It was actually less problematic than I thought, although VMWare doesn&#8217;t support the process end to end. The steps you have to go through are: Locate vmware-vdiskmanager.exe which, on my machine, is in C:\Program Files\VMware\VMware Workstation. Using the examples here together with [...]]]></description>
			<content:encoded><![CDATA[<p>I recently increased my VMWare disk image size from 10 to 15 GB. It was actually less problematic than I thought, although VMWare doesn&#8217;t support the process end to end. </p>
<p>The steps you have to go through are:</p>
<ol>
<li>Locate <a href="http://www.vmware.com/support/ws45/doc/disks_vdiskmanager_ws.html">vmware-vdiskmanager.exe</a> which, on my machine, is in C:\Program Files\VMware\VMware Workstation.</li>
<li>Using the examples <a href="http://www.vmware.com/support/ws45/doc/disks_vdiskmanager_eg_ws.html">here</a> together with the /? switch, the program can be invokes like:
<pre>
vmware-vdiskmanager.exe -x 15GB "path to image.vmdk"
</pre>
<p>to make the new image 15 GB of size. During the enlargement process the tool creates a temporary copy the image, so you must have sufficient space on your host environment for this. Also note that this example doesn&#8217;t preallocate disk space. What this means is that although the size is logically increased to 15 GB, the image doesn&#8217;t initially grow larger on disk.</li>
<li>Now the image can contain 15 GB of data, but the guest operation system doesn&#8217;t automatically pick up the change in disk size. If you boot Windows, it&#8217;ll tell you the disk size is 10 GB, the size the disk had when Windows was installed on it. Therefore, we need to use PartitionMagic or simular tool to make Windows adjust as discribed <a href="http://www.vmware.com/support/kb/enduser/std_adp.php?p_faqid=1647">here</a>.
</ol>
<p>All in all the process took roughly 80 minutes on my laptop. Unfortunately, it didn&#8217;t make Visual Studio 2005 run any faster than on the W2k3 server running out of disk space. I guess the dramatic slowdown is just a necessary evil of running Visual Studio 2005 in a virtualized environment on a laptop as the development environment is not the fastest running on native hardware either.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2007/03/22/increasing-vmware-disk-size/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The su of Windows</title>
		<link>http://www.bugfree.dk/blog/2007/02/25/the-su-of-windows/</link>
		<comments>http://www.bugfree.dk/blog/2007/02/25/the-su-of-windows/#comments</comments>
		<pubDate>Sun, 25 Feb 2007 09:58:11 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Windows]]></category>
		<category><![CDATA[Tip]]></category>
		<category><![CDATA[Tool]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2007/02/25/the-su-of-windows/</guid>
		<description><![CDATA[On Linux based system, it&#8217;s a common idiom to impersonate the root user whenever you have to perform a privileged operation. This is typically accomplished using the su command, which, although used less frequently, has a Windows equivalent, called runat.exe. runat.exe turned out to be quite useful when I had to do some work with [...]]]></description>
			<content:encoded><![CDATA[<p>On Linux based system, it&#8217;s a common idiom to impersonate the root user whenever you have to perform a privileged operation. This is typically accomplished using the <code>su</code> command, which, although used less frequently, has a Windows equivalent, called <code>runat.exe</code>. </p>
<p><code>runat.exe</code> turned out to be quite useful when I had to do some work with MS SQL 2005 Server, Analysis Service. The thing with Analysis Service is that it&#8217;s <a href="http://msdn2.microsoft.com/en-us/library/ms144288.aspx">Windows authentication only</a>, whereas MS SQL 2005 Server supports <a href="http://msdn2.microsoft.com/en-us/library/ms144284.aspx">mixed mode authentication</a>.</p>
<p>My only option for getting in touch with Analysis Service was using SQL Server Management Studio by impersonating an existing Windows user, who is allowed access to Analysis Service (I didn&#8217;t have the option of creating a new account on the machine running Analysis Service and the machine wasn&#8217;t allowed to trust the domain my desktop computer was on (it&#8217;s a tough world out there)).</p>
<p>So, using <code>runat.exe</code>, I ran the command below (on one line, from a shortcut), in effect causing the display of a prompt asking for the password for my_impersonated_user. Upon entering the password <code>sqlwb.exe</code> starts up as if it was run from the local my_impersonated_user account. </p>
<pre>
C:\\Windows\\System32\\runas.exe /user:my_impersonated_user 
"c:\\Program Files\\Microsoft SQL Server\\90\\Tools\\
Binn\\VSShell\\Common7\\IDE\\sqlwb.exe"
</pre>
<p>For the command to succeed my_impersonated_user have to be a user on the local machine with a username and password identical to the user that is allowed access to MS SQL 2005 Server/Analysis service. </p>
<p>Now Windows lets you logon to Analysis Service even if your local machine is on a different domain than the MS SQL 2005 Server.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2007/02/25/the-su-of-windows/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cogan&#8217;s rules to better email</title>
		<link>http://www.bugfree.dk/blog/2007/01/23/cogans-rules-to-better-email/</link>
		<comments>http://www.bugfree.dk/blog/2007/01/23/cogans-rules-to-better-email/#comments</comments>
		<pubDate>Tue, 23 Jan 2007 17:54:46 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Process]]></category>
		<category><![CDATA[Tip]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2007/01/23/cogans-rules-to-better-email/</guid>
		<description><![CDATA[Don&#8217;t you just hate it when you send an email to someone and then patiently wait for a reply never to show up. Quite often because the email quickly moved so far down the inbox that it&#8217;s now mentally gone. Or how about those people who always hit &#8220;new&#8221; when they really should&#8217;ve hit &#8220;reply&#8221;. [...]]]></description>
			<content:encoded><![CDATA[<p>Don&#8217;t you just hate it when you send an email to someone and then patiently wait for a reply never to show up. Quite often because the email quickly moved so far down the inbox that it&#8217;s now mentally gone. Or how about those people who always hit &#8220;new&#8221; when they really should&#8217;ve hit &#8220;reply&#8221;.</p>
<p>What to do about those people? Force them to read up on <a href="http://www.ssw.com.au/ssw/Standards/Rules/RulesToBetterEmail.aspx">Adam Cogan&#8217;s rules to better email</a>, of course.</p>
<p>My favorite one is probably rule #2, the one about moving email from your inbox to a special folder when you&#8217;ve replied to or otherwise handled it. This way, items in your inbox can be considered a task list. </p>
<p>Also, #43 about not sending email immediately because you&#8217;ll often think of something you missed is a good one. Unfortunately, delayed sending isn&#8217;t supported by most public web mail providers.</p>
<p><b>Update: July 26</b>: Inspired by David Allen&#8217;s <a href="http://www.davidco.com">Getting Things Done</a>, this <a href="http://video.google.com/videoplay?docid=973149761529535925&#038;hl=en">Inbox Zero</a> Google Tech Talk video details a slightly different approach for managing email. Also, the <a href="http://todotxt.com/">Todo.txt</a> site, co-created by <a href="http://lifehacker.com/">Lifehacker</a> <a href="http://ginatrapani.org/">Gina Trapani</a>, argues that using your inbox as a todo list is a bad habit and proposes a simpler solution.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2007/01/23/cogans-rules-to-better-email/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Certified Scrum master</title>
		<link>http://www.bugfree.dk/blog/2007/01/19/certified-scrum-master/</link>
		<comments>http://www.bugfree.dk/blog/2007/01/19/certified-scrum-master/#comments</comments>
		<pubDate>Fri, 19 Jan 2007 18:28:03 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Process]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2007/01/19/certified-scrum-master/</guid>
		<description><![CDATA[Just wanted to mention that I&#8217;m now a Certified Scrum Master. I was even fortunate enough to have James Coplien as one of the trainers. All I need now is a project where I can actually apply what I&#8217;ve learned.]]></description>
			<content:encoded><![CDATA[<p>Just wanted to mention that I&#8217;m now a <a href="http://en.wikipedia.org/wiki/Scrum_master">Certified Scrum Master</a>. I was even fortunate enough to have <a href="http://en.wikipedia.org/wiki/James_O._Coplien">James Coplien</a> as one of the trainers. </p>
<p>All I need now is a project where I can actually apply what I&#8217;ve learned.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2007/01/19/certified-scrum-master/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating a DSL for personal accounting in Ruby</title>
		<link>http://www.bugfree.dk/blog/2006/12/30/creating-a-dsl-for-personal-accounting-in-ruby/</link>
		<comments>http://www.bugfree.dk/blog/2006/12/30/creating-a-dsl-for-personal-accounting-in-ruby/#comments</comments>
		<pubDate>Sat, 30 Dec 2006 14:13:58 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2006/12/30/creating-a-dsl-in-ruby-for-personal-accounting/</guid>
		<description><![CDATA[I’ve been reading up on Ruby (and Rails) lately, and I’m in need of a project for getting hands on with the nuts and bolts of the language. So as an exercise I’ve been thinking about constructing a DSL for describing accounting transactions (debits and credits) and describing reports (income vs. expense and account summaries). [...]]]></description>
			<content:encoded><![CDATA[<p>I’ve been reading up on <a href="http://www.ruby-lang.org/en/">Ruby</a> (and <a href="http://www.rubyonrails.org/">Rails</a>) lately, and I’m in need of a project for getting hands on with the nuts and bolts of the language. </p>
<p>So as an exercise I’ve been thinking about constructing a <a href="http://en.wikipedia.org/wiki/Domain_Specific_Language">DSL</a> for describing accounting transactions (debits and credits) and describing reports (income vs. expense and account summaries).</p>
<p>For a couple of years, I’ve been using <a href="http://gnucash.org/">Gnucash</a>, a double entry accounting system, for simple personal accounting. It works great except it&#8217;s Linux only, which is not ideal since I’ve been running Windows on my desktop lately. So every time I need to do accounting stuff, I’ve got to fire up VMware.</p>
<p>Instead it would be fun to literally do double entry accounting in Ruby, by expressing each transaction and report in terms of the DSL.</p>
<p>This way my accounting information can all be recorded using the DSL and when entering the information, you can make use of the arithmetic features and function of Ruby itself, e.g., if an entry must be the sum of several values, you can enter each value and have Ruby do the summing.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2006/12/30/creating-a-dsl-for-personal-accounting-in-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Text files vs. personal wiki</title>
		<link>http://www.bugfree.dk/blog/2006/12/04/text-files-vs-personal-wiki/</link>
		<comments>http://www.bugfree.dk/blog/2006/12/04/text-files-vs-personal-wiki/#comments</comments>
		<pubDate>Sun, 03 Dec 2006 22:18:59 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Windows]]></category>
		<category><![CDATA[Process]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Tool]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2006/12/04/text-files-vs-personal-wiki/</guid>
		<description><![CDATA[I have quite a few small text files lying around, containing everything from to-do lists to shopping lists to code snippets to small howto&#8217;s. Now, instead of having all those text files floating around as regular files, nine months ago I decided to move them into a locally stored, for security reasons, personal wiki. Among [...]]]></description>
			<content:encoded><![CDATA[<p>I have quite a few small text files lying around, containing everything from to-do lists to shopping lists to code snippets to small howto&#8217;s. Now, instead of having all those text files floating around as regular files, nine months ago I decided to move them into a locally stored, for security reasons, personal wiki.</p>
<p>Among the good wiki engines out there (most notably <a href="http://www.mediawiki.org/wiki/MediaWiki">MediaWiki</a>, <a href="http://moinmoin.wikiwikiweb.de">MoinMoin</a>, and <a href="http://www.flexwiki.com">FlexWiki</a>), I went with FlexWiki, because it being asp.net based means that all the software required for a basic configuration ships with Windows. In addition, FlexWiki&#8217;s provider-based storage model lets you store pages in an MS SQL server, if you want to. </p>
<p>My incentive for going the wiki way was that I expected my documents to become more structured when making use of the typical wiki-like features &#8230;</p>
<ul>
<li>Documents are automatically linked together.<br />
I found my pages to be fairly independent, so hyperlinks are almost never present.</li>
<li>All modifications are recoded.<br />
Versioning isn&#8217;t really that big an issue, because I usually add contents to the end of a page rather than changing existing contents, and for pages such as a shopping list, I don&#8217;t really need versioning.</li>
<li>More sophisticating layout capabilities.<br />
Although I occasionally created a table and used colors, generally I can do with simple formatting. For those few cases where I can&#8217;t, a Word document is in place, since it’s equally well indexed by MS or Google desktop search engines.</li>
</ul>
<p>&#8230; but most of the time, I didn&#8217;t make use of the features FlexWiki provided over text files. So, if you also factor in the disadvantages &#8230;</p>
<ul>
<li>Extra infrastructure required.<br />
Web server, and possibly an SQL server, is a must-have-installed. Also, you probably need to figure out how to configure the web server so you don&#8217;t share your live with the world.</li>
<li>Browser required for page edit.<br />
After launching the browser, you must navigate to the wiki page, which may add considerable overhead for quick edits as opposed to simply double clicking a text file from within Explorer.</li>
<li>Lacking WYSIWYG support.<br />
With FlexWiki, editing a page is a two-step process. First you write content in a markup language. Then you click &#8220;Save&#8221; and the browser switches to display view, where your markup is converted to html. Now, if the result is not what you expected, you have to repeat the cycle.</li>
<li>Build-in search less powerful than desktop search engines.<br />
If you use the file system for storing wiki pages then the pages are also searchable by desktop search engines. However, if you opt for MS SQL storage, you have to rely on the build-in search capabilities of the wiki to find pages.</li>
<li>Backup is more involved.<br />
Backing up and restoring a database is more complicated than copying a directory.</li>
</ul>
<p>&#8230; I&#8217;ve decided that the wiki doesn&#8217;t cut it for me: simply because there is less overhead associated with editing text or even Word documents and because with desktop search engines I retain most of the properties I need.</p>
<p>This doesn&#8217;t mean that a wikis aren&#8217;t suited for maintaining a corpus of personal information; just that the corpus should serve a different purpose to make better use of wiki features.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2006/12/04/text-files-vs-personal-wiki/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to efficiently consume a podcast</title>
		<link>http://www.bugfree.dk/blog/2006/11/25/how-to-efficiently-consume-a-podcast/</link>
		<comments>http://www.bugfree.dk/blog/2006/11/25/how-to-efficiently-consume-a-podcast/#comments</comments>
		<pubDate>Sat, 25 Nov 2006 17:13:17 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Tip]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2006/11/25/how-to-efficiently-consume-a-podcast/</guid>
		<description><![CDATA[How often do you find yourself listening to or viewing podcasts from ITConversations, .Net Rocks, Channel 9, or dnrTV? Now, how often do you crank up your playback speed? I&#8217;ve been conducting some un-scientific experiments with increasing the playback speed with Media Player (only supports 1.5x) and my mp3-player (supports variable speed). My conclusion is [...]]]></description>
			<content:encoded><![CDATA[<p>How often do you find yourself listening to or viewing podcasts from <a href="http://www.itconversations.com">ITConversations</a>, <a href="http://dotnetrocks.com">.Net Rocks</a>, <a href="http://channel9.msdn.com">Channel 9</a>, or <a href="http://dnrtv.com">dnrTV</a>?</p>
<p>Now, how often do you crank up your playback speed? </p>
<p>I&#8217;ve been conducting some un-scientific experiments with increasing the playback speed with <a href="http://www.microsoft.com/windows/windowsmedia/player/10/default.aspx">Media Player</a> (only supports 1.5x) and my <a href="http://www.web-shoppen.dk/web-shoppen/displayProduct.jsp?link=kelkoo&#038;displayProduct=0FFAF4BCAA266CE8BB63954C9F71EAF6">mp3-player</a> (supports variable speed).</p>
<p>My conclusion is that listening to or viewing a podcast at about 1.5x the original speed is really the optimal trade-off between time consumption, not stressing the brain, and still be able to comprehend the contents.</p>
<p>And I save 15 minutes of every hour consuming podcasts. </p>
<p>Just make sure you don&#8217;t start speaking 1.5x faster because you listen to too many podcasts.</p>
<p><b>Update, August 6, 2007</b>: <a href="http://www.stevepavlina.com/blog/2007/08/overclock-your-audio-learning">Steve Pavlina</a> describes many of the same thoughts, although he&#8217;s an advocate of a much higher speed. Steve&#8217;s blog entry mentions that &#8220;&#8230; in the latest version of Windows Media Player, click the arrow below “Now Playing.”  Then click Enhancements -> Show Play Speed Settings&#8221; as a way to bring up a speed slider. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2006/11/25/how-to-efficiently-consume-a-podcast/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CruiseControl.net and build queues</title>
		<link>http://www.bugfree.dk/blog/2006/11/19/cruisecontrolnet-and-build-queues/</link>
		<comments>http://www.bugfree.dk/blog/2006/11/19/cruisecontrolnet-and-build-queues/#comments</comments>
		<pubDate>Sun, 19 Nov 2006 09:07:10 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Process]]></category>
		<category><![CDATA[Tool]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2006/11/19/build-queues-with-cruisecontrolnet/</guid>
		<description><![CDATA[(I&#8217;ve created a Download page for the tool described in this post, with a short description of prerequisites and how to install it.) For team development a way is needed to ensure that team members doesn&#8217;t inadvertently break the shared code, e.g., a developer forgets to commit all files related to a change, which is [...]]]></description>
			<content:encoded><![CDATA[<p>(I&#8217;ve created a <a href="http://www.bugfree.dk/blog/software/ccnetserializer/">Download</a> page for the tool described in this post, with a short description of prerequisites and how to install it.)</p>
<p>For team development a way is needed to ensure that team members doesn&#8217;t inadvertently break the shared code, e.g., a developer forgets to commit all files related to a change, which is something not easily fixable by other developers.</p>
<p>Also, the team might want to run post-compile tasks, such as unit tests, on a dedicated machine to avoid the works-on-my-machine syndrome.</p>
<p>Ideally, the project’s code should always go from one stable state to another so that a developer doesn’t get broken code the next time he synchronizes with source control. </p>
<p>One way to achieve this is by means of <a href="http://www.martinfowler.com/articles/continuousIntegration.html">continuous integration</a> of changes into the code. Either by rolling your own build script that monitors source control for changes to trigger a build and inform developers of the result or by leveraging an existing continuous integration solution, such as <a href="http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET">CruiseControl.net</a> (ccnet): a continuous integration server, an asp.net based front-end, and a desktop client.</p>
<p>Although CruiseControl (both the Java and .Net incarnation) appears to be a popular choice among developers, I find it somewhat immature: it violates the <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">dry principle</a> in its projects configuration file and, worst of all, it doesn&#8217;t support build queues to ensure that only one of several projects are actually building at once. </p>
<p>It&#8217;s not a problem for ccnet itself to perform parallel continuous integration. However, the build chain is no stronger than the weakest link, which in my case is devenv.exe, the Visual Studio executable used by ccnet to build the application (by running devenv.exe from the command line with a couple of arguments, you can leverage the build system within Visual Studio from a script). </p>
<p>The downside to using devenv.exe, however, is that all running instances share a temporary build folder for compiler output. Thus, when ccnet does continuous integration of branches in parallel, the instances of devenv.exe spawned by ccnet compete for write access to identically named files, namely the executables generated by the compiler.</p>
<p>Not surprisingly, this results in build failures for one or more ccnet projects, although there is nothing wrong with the code. </p>
<p>In my experience from the trenches this happens too often to be ignored for any serious use of ccnet: It&#8217;s just too common for a developer to cross-commit a bugfix to several branches or for independent developers to commit to their working branches in between when ccnet checks the branch for updates. </p>
<p>Having these false negatives make the team members not trust ccnet and not take proper action whenever they see a build failure, thus rendering continuous integration useless.</p>
<p>One solution to the above file locking problem is to serialize the builds manually by building branches at predefined intervals, thus interleaving the builds so that they shouldn&#8217;t be able to overlap. As a result the developer may have to wait a fair amount of time to be sure his latest commit doesn&#8217;t breaks anything. Also, if a build has not finished when the next is scheduled to start, it may cause a cascade of broken builds to occur until the interleaving is properly realigned. </p>
<p>Another solution is to head over to <a href="http://jayflowers.com/WordPress/?p=72">Jay Flowers</a>. He has branched off the official 1.0 version of ccnet and created a ccnet that allows for a lot more constraints than just serializing builds. It happens at the expense of running the non-official, not-recent version of ccnet, though.</p>
<p>My solution to the parallel build problem was to write a front-end for ccnet that implements build queues without the knowledge of ccnet, i.e., by means of checking for changes on a configurable number of branches. If a change is detected, the branch is enqueued. Then when all branches are checked, the tool force builds each branch, monitoring the state of the ccnet server to ensure that only one branch is building at a time. </p>
<p>With this solution you integrate the nice features of ccnet, such as the nice webgui for displaying what went wrong with a build and the systray application that goes green, yellow, or red depending on the state of your builds, with rapid feedback in a way that is compatible with Visual Studio&#8217;s integrated build engine.</p>
<p>The biggest downside, however, is that you can no longer see the changes that triggered a build from the web gui as ccnet is no longer in charge of cvs operations.</p>
<p>The tool is roughly 100 lines of <a href=”http://www.codeplex.com/Wiki/View.aspx?ProjectName=IronPython”>IronPython</a> code and works by spawning cvs.exe, synchronizing a number of working copies with the cvs repository, and in the process  monitors the output of cvs.exe for changes, additions, and removals of files to the working copies. </p>
<p>The state of CruiseControl is determined by screen scraping the webgui and builds are forced by simulating a click on the &#8220;build&#8221; button for the ccnet project in the webgui for which a change was detected.</p>
<p>The url of the ccnet webgui, the path to the cvs.exe, and mappings between the path on disk where each working copy resides and the corresponding name of the ccnet project are stored in the tools configuration file, which is itself Python code loaded into the tool on startup. </p>
<p>Using Python as a language for your configuration file, you don’t have to invent your own language or use verbose xml, which requires you to write code for parsing it.</p>
<p>PS: I recently stumbled across the <a href="http://ccnetplugins.sourceforge.net/">Sequential Task Plug In</a> that I want to try out sometime.</p>
<p><b>Update, April 16</b>: It has come to my attention that there is a way to minimize duplication in the configuration file. It involves &#8220;&#8230; users to set up DTD entities within the CCNet configuration&#8221; as mentionen <a href="http://dotnetjunkies.com/WebLog/exortech/archive/2007/04/15/225924.aspx">here</a>. I haven&#8217;t tried it, though.</p>
<p><b>Update, August 10</b>: CruiseControl.net 1.3 now comes with a build-in queue feature.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2006/11/19/cruisecontrolnet-and-build-queues/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CVS merge bit me</title>
		<link>http://www.bugfree.dk/blog/2006/09/24/cvs-merge-bid-me/</link>
		<comments>http://www.bugfree.dk/blog/2006/09/24/cvs-merge-bid-me/#comments</comments>
		<pubDate>Sun, 24 Sep 2006 09:42:48 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Tip]]></category>
		<category><![CDATA[Tool]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2006/09/24/cvs-merge-bid-me/</guid>
		<description><![CDATA[I&#8217;m currently managing the merge operations for a CVS repository with a branch layout looking partly as follows: At some point in the past HEAD branched into B1, which subsequently branched into B1.1. Then development on B1 completed and it was merged back into HEAD so a release branch B2 could be created. B1.1, however, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m currently managing the merge operations for a CVS repository with a branch layout looking partly as follows:</p>
<p><img id="image15" height=140 alt=cvs_merge.GIF src="http://www.bugfree.dk/blog/wp-content/uploads/2006/09/cvs_merge.GIF" /></p>
<p>At some point in the past HEAD branched into B1, which subsequently branched into B1.1. Then development on B1 completed and it was merged back into HEAD so a release branch B2 could be created. B1.1, however, kept living its separate life for a while, because the features added aren&#8217;t to be released until with release branch B5. This also goes for the changes made to B3, so it makes sense for B1.1 to be merged into B3.</p>
<p>As a result, I just spend a few hours on tracking down a merge issue resulting from this merge, because a change made in B1 wasn&#8217;t present in B3 after B1.1 was merged into this branch. I finally figured out why: suppose a line is removed in B1 before the spin-off of B1.1. After that the very same line is added back in. Now when B1.1 is merged into B3, the line is removed again. There is no merge conflict at this point, because from CVS&#8217; point of view it&#8217;s a clean merge.</p>
<p>It seems obvious what happened when looking at the diagram, but when you&#8217;re working with a large repository with lots of modified files and you&#8217;re merging code not written by yourself, this sort of indirect change propagation may inevitably bite you as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2006/09/24/cvs-merge-bid-me/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Powertools from SysInternals</title>
		<link>http://www.bugfree.dk/blog/2006/09/17/powertools-from-sysinternals/</link>
		<comments>http://www.bugfree.dk/blog/2006/09/17/powertools-from-sysinternals/#comments</comments>
		<pubDate>Sun, 17 Sep 2006 13:26:57 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Windows]]></category>
		<category><![CDATA[Tip]]></category>
		<category><![CDATA[Tool]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2006/09/17/powertools-from-sysinternals/</guid>
		<description><![CDATA[I use the SysInternals tools (now acquired by the Empire). The ones I use most often are: PageDefrag PageDefrag uses advanced techniques to provide you what commercial defragmenters cannot: the ability for you to see how fragmented your page file and Registry hives are, and to defragment them. In addition, it defragments event log files [...]]]></description>
			<content:encoded><![CDATA[<p>I use the <a href="http://www.sysinternals.com/">SysInternals</a> tools (now acquired by the <a href="http://microsoft.com">Empire</a>). The ones I use most often are:</p>
<ul>
<li><a href="http://www.sysinternals.com/utilities/pagedefrag.html">PageDefrag</a><br />
<blockquote><p>
PageDefrag uses advanced techniques to provide you what commercial defragmenters cannot: the ability for you to see how fragmented your page file and Registry hives are, and to defragment them. In addition, it defragments event log files and Windows 2000/XP hibernation files [...].
</p></blockquote>
<p>Has the ability to run at the next or every boot (that&#8217;s how it gets exclusive access to the system files).  Running it every time I boot typically adds 10-20 seconds to my boot time, but I guess it depends on how often you boot, the amount of physical memory, and what kind of applications you run.</p>
<li><a href="http://www.sysinternals.com/utilities/contig.html">Contig</a><br />
<blockquote><p>
Contig is a single-file defragmenter that attempts to make files contiguous on disk. It’s perfect for quickly optimizing files that are continuously becoming fragmented, or that you want to ensure are in as few fragments as possible.
</p></blockquote>
<p>Also has a recursive switch, so you can specify C:\ as the starting point and it&#8217;ll defragment its way through your entire drive.</p>
<li><a href="http://www.sysinternals.com/utilities/shareenum.html">ShareEnum</a><br />
<blockquote><p>
When you run ShareEnum it uses NetBIOS enumeration to scan all the computers within the domains accessible to it, showing file and print shares and their security settings.
</p></blockquote>
<p>A worthy replacement for Network Neighborhood, although it sometimes is not able to find any shares, although I know there&#8217;s quite a few out there. </p>
<li><a href="http://www.sysinternals.com/utilities/autoruns.html">Autoruns</a><br />
<blockquote><p>
This utility, which has the most comprehensive knowledge of auto-starting locations of any startup monitor, shows you what programs are configured to run during system boot or login, and shows you the entries in the order Windows processes them. These programs include ones in your startup folder, Run, RunOnce, and other Registry keys.
</p></blockquote>
<p>On my computer, it takes longer for Windows to become responsive after log on than it takes Windows to boot and display the log on screen, because Windows loads a ton of software, fills up the systray, and starts various services I really don&#8217;t need. </p>
<p>Services such as Remote Registry for accessing the registry across the network, Windows Image Acquisition for popping up a dialog box when I scan an image on the scanner I don&#8217;t have, or Windows Zero Configuration for managing the WLAN access I never use. </p>
<p>Those services are all on by default and can be disabled using AutoRuns (or using Control panel => Administrative tools => Services).</p>
<li><a href="http://www.sysinternals.com/utilities/processexplorer.html">Process Explorer</a><br />
<blockquote><p>
The Process Explorer display consists of two sub-windows. The top window always shows a list of the currently active processes, including the names of their owning accounts, whereas the information displayed in the bottom window depends on the mode that Process Explorer is in: if it is in handle mode you&#8217;ll see the handles that the process selected in the top window has opened; if Process Explorer is in DLL mode you&#8217;ll see the DLLs and memory-mapped files that the process has loaded. Process Explorer also has a powerful search capability that will quickly show you which processes have particular handles opened or DLLs loaded.
</p></blockquote>
<p>The quote speaks for itself.
</ul>
<p>There&#8217;s a lot more tools where these came from. Among the ones I use less frequently are FileMon and Regmon for real-time monitoring of file system and registry access, respectively. Also, I use TCPView as a more user friendly replacement for the netstat command.</p>
<p>Finally, take a look at <a href="http://www.dnrtv.com/default.aspx?showID=35">dnrTV</a>, where <a href="http://www.hanselman.com/blog/">Scott Hanselman</a> recently showed off some of these tools.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2006/09/17/powertools-from-sysinternals/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Query transform with MSSQL server</title>
		<link>http://www.bugfree.dk/blog/2006/09/15/query-transformation-with-mssql-server/</link>
		<comments>http://www.bugfree.dk/blog/2006/09/15/query-transformation-with-mssql-server/#comments</comments>
		<pubDate>Fri, 15 Sep 2006 19:55:12 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Windows]]></category>
		<category><![CDATA[Tip]]></category>
		<category><![CDATA[Tool]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2006/09/15/query-transformation-with-mssql-server/</guid>
		<description><![CDATA[Ever found yourself struggling with a big chuck of embedded SQL failing on you? Oftentimes because of a trivial, but hard to spot, syntax (or semantic) error introduced as part of your dynamic query composition process. Typically, you&#8217;d target your frustration at the debugger and insert a breakpoint around the problematic part of your code [...]]]></description>
			<content:encoded><![CDATA[<p>Ever found yourself struggling with a big chuck of embedded SQL failing on you? Oftentimes because of a trivial, but hard to spot, syntax (or semantic) error introduced as part of your dynamic query composition process.</p>
<p>Typically, you&#8217;d target your frustration at the debugger and insert a breakpoint around the problematic part of your code to extract the SQL and copy it into the Query Analyzer for investigation.</p>
<p>Unfortunately, pasting the SQL into Query Analyzer causes the statement to appear on one line entirely. You then find yourself inserting new line characters for readability and for making the error message more precise.</p>
<p>Transforming SQL this way is tedious, boring, and crying for automation. Fortunately, Enterprise Manager responds well to these cries. Just drill down to a table view of your database, right click on a table, and select &#8220;Open table&#8221; followed by &#8220;Query&#8221;.</p>
<p>Now paste your extracted SQL into the text portion of the Query by Example window and hit &#8220;Run&#8221;. Although the query might not actually execute, it&#8217;s transformed into a more readable one. </p>
<p>Obviously, you could start and stay in the QBE window. Personally, though, I dislike QBE as a working environtment beyond for layout beautification, so I usually copy the transformed query into Query Analyzer.</p>
<p>By the way, the transform also comes in handy if you want to make sure your query doesn&#8217;t contain any camouflaged expensive joins, e.g., for a query with inner joins done using where clauses, QBE transforms it into explicit inner joins.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2006/09/15/query-transformation-with-mssql-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows Vista RC1 rocks</title>
		<link>http://www.bugfree.dk/blog/2006/09/12/windows-vista-rc1-rocks/</link>
		<comments>http://www.bugfree.dk/blog/2006/09/12/windows-vista-rc1-rocks/#comments</comments>
		<pubDate>Tue, 12 Sep 2006 18:52:11 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Windows]]></category>
		<category><![CDATA[Tip]]></category>
		<category><![CDATA[Tool]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/2006/09/12/windows-vista-rc1-rocks/</guid>
		<description><![CDATA[I&#8217;ve been playing around with different setups of Windows Vista RC1 the last couple of days. Just getting Vista to install was an challenge in itself as RC1 refuses to install on VMWare Workstation. It stalls at &#8220;Windows is loading files &#8230;&#8221;. Apparently the subsequent switch into graphics mode causes Vista to hang, because Vista [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been playing around with different setups of <a href="http://www.microsoft.com/Windowsvista">Windows Vista</a> RC1 the last couple of days. Just getting Vista to install was an challenge in itself as RC1 refuses to install on VMWare Workstation.</p>
<p>It stalls at &#8220;Windows is loading files &#8230;&#8221;. Apparently the subsequent switch into graphics mode causes Vista to hang, because Vista all the sudden doesn&#8217;t properly support the emulated video hardware of VMWare.</p>
<p>That&#8217;s odd, because I previously installed Beta 2 on VMWare without any sign of trouble (could it be that MS wants people to try out RC1 on their <a href="http://www.microsoft.com/Windows/virtualpc/default.mspx">free</a> Virtual PC? By the way, <a href="http://www.vmware.com/products/server/">VMWare Server</a> is free too).</p>
<p>Luckily, <a href="http://www.joelonsoftware.com/">Joel on Software</a>&nbsp;provides a <a href="http://www.joelonsoftware.com/items/2006/09/08b.html">solution</a>&nbsp;to the VMWare issue, by adding</p>
<pre class="prettyprint lang-cs">
svga.maxWidth = "640" 
svga.maxHeight = "480"
</pre>
<p>to the configuration file for your virtual machine prior to booting the Vista DVD. It&#8217;ll force the installer to run in SVGA mode. Then when the installation is complete and you&#8217;ve installed the VMWare tools, remove the above lines and Vista shines.</p>
<p>My intention was to run Vista in VMWare on a secondary computer and connect to it via Remote Desktop. For some yet to be uncovered reason, however, I wasn&#8217;t able to connect from my WinXP machine. Perhaps the host OS&nbsp;blocked the incoming request or perhaps Vista just wasn&#8217;t properly configured.</p>
<p>Anyway, I decided to run Vista on the bare hardware instead, so I fired up PartitionMagic. Unfortunately some guy accidentally cut power while PartitionMagic was doing its shrink-existing-partition-to-create-space-for-an-additional-one magic. After that the existing OS chickened out and bluescreened on me, so out everything went and in Vista came.</p>
<p>Thus, now I utilize a two-monitor setup, running Vista on a native 2.6GHz&nbsp;processor&nbsp;with 2GB of memory on one monitor and WinXP on the other. Unfortunately, the Vista machine has a crappy video card, so no fancy, transparent UI for me (unless I find a workaround).</p>
<p>As a final note, I&#8217;m using <a href="http://synergy2.sourceforge.net/">Synergy</a>&nbsp;to seamlessly share one mouse and keyboard between the physical machines as if it was one machine with dual head video output.</p>
<p>Way cool!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2006/09/12/windows-vista-rc1-rocks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>70-536: MCTS, part 1 of 2</title>
		<link>http://www.bugfree.dk/blog/2006/09/09/70-536-mcts-part-1-of-2/</link>
		<comments>http://www.bugfree.dk/blog/2006/09/09/70-536-mcts-part-1-of-2/#comments</comments>
		<pubDate>Sat, 09 Sep 2006 15:45:04 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Book]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=10</guid>
		<description><![CDATA[Just received my copy of the Microsoft .Net Framework 2.0, Application Development Foundation book. This book is essential in preparing for the 70-536 certification exam. It&#8217;s the first of two exams one has to pass to become a MCTS (Microsoft Certified Technology Specialist), specializing in either web or Windows application development. I&#8217;d rather have used [...]]]></description>
			<content:encoded><![CDATA[<p>Just received my copy of the <a href="http://www.amazon.com/MCTS-Self-Paced-Training-Exam-70-536/dp/0735622779/sr=8-1/qid=1157816444/ref=pd_bbs_1/102-1619472-2619335?ie=UTF8&#038;s=books">Microsoft .Net Framework 2.0, Application Development Foundation</a> book.</p>
<p>This book is essential in preparing for the 70-536 certification exam. It&#8217;s the first of two exams one has to pass to become a MCTS (Microsoft Certified Technology Specialist), specializing in either web or Windows application development. </p>
<p>I&#8217;d rather have used <a href="http://www.amazon.com/MCTS-70-536-Exam-Prep-Foundation/dp/078973558X/sr=8-2/qid=1157817156/ref=pd_bbs_2/102-1619472-2619335?ie=UTF8&#038;s=books">Amit Kalanis</a> book, but its shipping date just continues to get pushed. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2006/09/09/70-536-mcts-part-1-of-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to break Notepad</title>
		<link>http://www.bugfree.dk/blog/2006/09/02/how-to-break-notepad/</link>
		<comments>http://www.bugfree.dk/blog/2006/09/02/how-to-break-notepad/#comments</comments>
		<pubDate>Sat, 02 Sep 2006 20:23:03 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Windows]]></category>
		<category><![CDATA[Tip]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=8</guid>
		<description><![CDATA[Do the following: Open Notepad Type in &#8220;this app can break&#8221; (without the quotes) Save file Close Notepad Re-open saved file in Notepad Now Notepad displays funny looking foreign characters. This is caused by a &#8220;bug&#8221; in the Win32 function IsTextUnicode, which Notepad calls to heuristically determine if a file is Unicode encoded. For more [...]]]></description>
			<content:encoded><![CDATA[<p>Do the following:</p>
<ul>
<li>Open Notepad</li>
<li>Type in &#8220;this app can break&#8221; (without the quotes)</li>
<li>Save file</li>
<li>Close Notepad</li>
<li>Re-open saved file in Notepad</li>
</ul>
<p>Now Notepad displays funny looking foreign characters.</p>
<p>This is caused by a &#8220;bug&#8221; in the Win32 function <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/unicode_81np.asp">IsTextUnicode</a>, which Notepad calls to heuristically determine if a file is Unicode encoded.</p>
<p>For more in-depth info click <a href="http://apipes.blogspot.com/2006/06/this-api-can-break.html">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2006/09/02/how-to-break-notepad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting into Python loops</title>
		<link>http://www.bugfree.dk/blog/2006/01/13/getting-into-python-loops/</link>
		<comments>http://www.bugfree.dk/blog/2006/01/13/getting-into-python-loops/#comments</comments>
		<pubDate>Fri, 13 Jan 2006 18:12:00 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=7</guid>
		<description><![CDATA[Looping is such a commonly used construct that I thought I&#8217;d do an informal comparison of the flavors of loops provided. For comparison, I define a function for scaling a list using (1) list comprehension, (2) the map function, (3) the for loop, and finally, just for the fun of it, (4) a recursive function. [...]]]></description>
			<content:encoded><![CDATA[<p>Looping is such a commonly used construct that I thought I&#8217;d do an informal comparison of the flavors of loops provided. For comparison, I define a function for scaling a list using (1) list comprehension, (2) the map function, (3) the for loop, and finally, just for the fun of it, (4) a recursive function. Mathematically, scaling a lists involves multiplying each elements by a scale factor, e.g., applying a scale factor of 10 to [1, 2, 3] yields [10, 20, 30].</p>
<p>The following code benchmarks each method, running it 500 times in a row. Furthermore, to ensure that the results are independent of the length of the list, I test each function on lists of sizes 1000 to 30000, in 100 increments, looking for a clear growth patterns (but found none).</p>
<pre>
<font color="#a020f0">from</font> time <font color="#a020f0">import</font> time
<font color="#a020f0">def</font> <font color="#0000ff">scale_using_recursion</font>(s, l):
    <font color="#a020f0">if</font> <font color="#a020f0">len</font>(l) == 0:
        <font color="#a020f0">return</font> []
    <font color="#a020f0">else:</font>
        <font color="#a020f0">return</font> [(l[0] * s)] + scale_using_recursion(s, l[1:])

<font color="#a020f0">def</font> <font color="#0000ff">scale_using_loop</font>(s, l):
    r = []
    <font color="#a020f0">for</font> e <font color="#a020f0">in</font> l:
        r.append(e * s)
    <font color="#a020f0">return</font> r

<font color="#a020f0">def</font> <font color="#0000ff">scale_using_map</font>(s, l):
    <font color="#a020f0">return</font> <font color="#a020f0">map</font>(<font color="#a020f0">lambda</font> e: e * s, l)

<font color="#a020f0">def</font> <font color="#0000ff">scale_using_list_comprehension</font>(s, l):
    <font color="#a020f0">return</font> [e * s <font color="#a020f0">for</font> e <font color="#a020f0">in</font> l]

<font color="#a020f0">def</font> <font color="#0000ff">run</font>(func, iterations, list_size):
    l = [e <font color="#a020f0">for</font> e <font color="#a020f0">in</font> <font color="#a020f0">range</font>(list_size)]
    t = time()
    [func(10, l) <font color="#a020f0">for</font> i <font color="#a020f0">in</font> <font color="#a020f0">range</font>(iterations)]
    <font color="#a020f0">return</font> (time() - t) / iterations

<font color="#a020f0">def</font> <font color="#0000ff">time_stuff</font>():
    iterations = 500

    <font color="#a020f0">for</font> list_size <font color="#a020f0">in</font> <font color="#a020f0">range</font>(1000, 30000, 100):
        t1 = run(scale_using_list_comprehension, iterations, list_size)
        t2 = run(scale_using_map, iterations, list_size)
        t3 = run(scale_using_loop, iterations, list_size)
        <font color="#a020f0">print</font>(<font color="#bc8f8f">"%s %s %s %s"</font>) % (list_size, t1/t1, t2/t1, t3/t1)

<font color="#a020f0">if</font> <font color="#a020f0">__name__</font> == <font color="#bc8f8f">"__main__"</font>:
    time_stuff()
</pre>
<p>The benchmark was performed under MS Windows, running Python 2.4.2. To make the results independent of the speed of the hardware, I compare each scaling method to the winner of the race, the list comprehension approach.</p>
<pre>
scale_using_list_comprehension:  1.0
scale_using_loop:                1.7
scale_using_map:                 2.1
(scale_using_recursion:         76.0)
</pre>
<p>Not surprisingly, the recursive approach is slow and infeasible for real use (and only tested on a list size of 500 to get an indication of relative performance). Generally, recursive functions are of limited use in Python because the interpreter doesn&#8217;t optimize for <a href="http://en.wikipedia.org/wiki/Tail_recursion">tail recursion</a>; a technique commonly used in functional languages that causes a tail recursion to get transformed into an iteration, making a recursive and an interative approach equally fast.</p>
<p>Lacking this features, Python blows up with a &#8220;RuntimeError: maximum recursion depth exceeded&#8221;, when it reaches the default recursion depth of 500. We could increase the number for certain situations, of course, but we would never truly be in safe range of the RuntimeError, and performing the way it does, it doesn&#8217;t really matter.</p>
<p>I was surprised to learn that map and for loops are roughly 70% and 110% slower, respectively, than list comprehension. I can&#8217;t really put my finger on what makes them so slow.</p>
<p>Although this isn&#8217;t the most scientific of studies, it does indicate that list comprehension is the way to go, if possible. Luckily, in most cases, list comprehension is also the shortest, the most elegant, and the most readable of the approaches. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2006/01/13/getting-into-python-loops/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Being a functional Pythonian</title>
		<link>http://www.bugfree.dk/blog/2006/01/04/being-a-functional-pythonian/</link>
		<comments>http://www.bugfree.dk/blog/2006/01/04/being-a-functional-pythonian/#comments</comments>
		<pubDate>Wed, 04 Jan 2006 19:43:00 +0000</pubDate>
		<dc:creator>Ronnie Holm</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Process]]></category>
		<category><![CDATA[Tool]]></category>

		<guid isPermaLink="false">http://www.bugfree.dk/blog/?p=6</guid>
		<description><![CDATA[In my first blog post, I&#8217;ll give an example of how functional programming (FP) in Python results in shorter, cleaner, and more concise code, compared to the equivalent in an imperative language like C#. I&#8217;ll use a real-world build tool I&#8217;ve written as the driving example. Typical tasks for such a tool would include, but [...]]]></description>
			<content:encoded><![CDATA[<p>In my first blog post, I&#8217;ll give an example of how <a href="http://gnosis.cx/publish/programming/charming_python_13.html">functional programming (FP) in Python</a> results in shorter, cleaner, and more concise code, compared to the equivalent in an imperative language like C#.</p>
<p>I&#8217;ll use a real-world build tool I&#8217;ve written as the driving example. Typical tasks for such a tool would include, but not be limited to, checking out sources from cvs, compiling the sources, and running NUnit against a number of generated targets.</p>
<p>Each such task may be defined as a function, taking any number of arguments and returning a list of the form:</p>
<pre>[status, [(command, output), (...)]]</pre>
<p>where status indicates binary success, command is the command run to complete the task and output is the output (stdout/stderr) of running the command. There may be more than one (command, output) tuple inside the sublist, if the task requires more than one command to complete.</p>
<p>In FP the <a href="http://python.org/doc/2.4.2/tut/node7.html#SECTION007100000000000000000">list</a> and <a href="http://python.org/doc/2.4.2/tut/node7.html#SECTION007300000000000000000">tuple</a> are fundamental and very powerful concepts, because they can easily be used to define complex structures for you to use when passing data around. They also facilitate easy processing using <a href="http://python.org/doc/2.4.2/tut/node7.html#SECTION007140000000000000000">list comprehension</a>, the functions build <a href="http://python.org/doc/2.4.2/tut/node7.html#SECTION007130000000000000000">into</a> the language, or functions of your own, providing elegant syntax for common operations, such as insertion, deletion, searching, slicing, etc.</p>
<p>These lists and tuples are more dynamic in nature than their array and struct counterparts in, say, C#. In fact, rather than creating user defined types, a list, or a tuple, or a combination often suffices, eliminating the need to write a lot of boilerplate code.</p>
<p>Now, to provide an example where Python&#8217;s FP support really kicks in with the build tool, is in the implementation of the code responsible for running NUnit against a number of targets:</p>
<pre>
<font color="#a020f0">def</font> <font color="#0000ff">NUnit</font>(nunitconsole, projectsOrAssemblies):
    results = [Run(<font color="#bc8f8f">"\""</font> + nunitconsole + <font color="#bc8f8f">"\" "</font> + source) 
              <font color="#a020f0">for</font> source <font color="#a020f0">in</font> projectsOrAssemblies]
    commands = [command[1][0] <font color="#a020f0">for</font> command <font color="#a020f0">in</font> results]
    outputs = [output[1][1] <font color="#a020f0">for</font> output <font color="#a020f0">in</font> results]
    failures = Sigma(re.findall(<font color="#bc8f8f">"Failures: (\d+)"</font>, <font color="#a020f0">str</font>(outputs)))
    <font color="#a020f0">return</font> [<font color="#a020f0">not</font> <font color="#a020f0">bool</font>(int(failures)), <font color="#a020f0">zip</font>(commands, outputs)]
</pre>
<p>This function relies heavily on the use of lists and list comprehension, rather than imperative style loops (which, of course, is also possible in Python). List comprehension is a construct that allows you to easily create a new list as a result of some processing on the elements of another.</p>
<p>A highlevel walk-through of the function: first the NUnit executable is invoked one target at a time. The Run function itself returns a list of the form [exitcode, (command, output)]; hence with n targets to test, the commands and outputs variables end up containing n commands and their output. The Failures variable counts the total number of failures accumulated across all targets, extracted as a list of strings matching the regular expression and summarized by the Sigma function.</p>
<p>Python doesn&#8217;t allow summing over a list of strings using its build-in Sum function. However, you can easily implement a Sum function that does in something along the lines of:</p>
<pre>
<font color="#a020f0">def</font> <font color="#0000ff">Sigma</font>(list): 
    <font color="#a020f0">return</font> <font color="#a020f0">reduce</font>(<font color="#a020f0">lambda</font> a, b: <font color="#a020f0">int</font>(a) + <font color="#a020f0">int</font>(b), list)
</pre>
<p>where reduce is a function present in most, if not all, FP languages, which reduces a list of values to a single value by applying a user-defined operation to pairwise values of the list.</p>
<p>Finally, the zip function is a build-in function, merging the elements of two lists into one.</p>
<p>Another important construct in FP is the lambda notation. It enables you to create an anonymous function, a function without an explicitly name, leading us to another key characteristic of FP: functions are treated as first-class citizens, in the sense that they may be passed around as just another variable, e.g., you can create a list of functions with parameters and then do the actual invocation at a later stage.</p>
<p>Using deferred invocation, the build tool manages the overall build process; in a config file, similar to a makefile, a list of lambdas are defined, each defining a function that executes a task. This provides us with a generic way of annotating a task and for each task to be run by a central runner, which takes care of logging description, command, and outcome to a html report. The prefs used as parameters to each task is an associated array of associated arrays of &#8230; well as many levels as you require.</p>
<p>In effect the config file defines a domain specific language, using regular Python syntax, which can easily be loaded into what corresponds to the make utility by an import statement:</p>
<pre>
prefs = {
    <font color="#bc8f8f">"cvs"</font> :
    {
        <font color="#bc8f8f">"cvs"</font> : <font color="#bc8f8f">"C:\\Program Files\\cvsnt\\cvs.exe"</font>, 
        <font color="#bc8f8f">"workingDirectory"</font> : <font color="#bc8f8f">"C:\\Inetpub\\wwwroot"</font>,
        <font color="#bc8f8f">"root"</font> : <font color="#bc8f8f">":pserver:foo:bar@1.2.3.4:/foobar"</font>,
        <font color="#bc8f8f">"module"</font> : <font color="#bc8f8f">"baz"</font>,
        <font color="#bc8f8f">"revision"</font> : <font color="#bc8f8f">"HEAD"</font>    
    },
    <font color="#bc8f8f">"nunit"</font> :  
    {
        <font color="#bc8f8f">"nunitconsole"</font> : <font color="#bc8f8f">"C:\\...\\nunit-console.exe"</font>,
        <font color="#bc8f8f">"projectsOrAssemblies"</font> : [C:\\Inetpub\\...\\foobar.nunit<font color="#bc8f8f">" ]
    },
    ...
}

tasks = [ ("</font>Checkout Foobar <font color="#a020f0">from</font> cvs<font color="#bc8f8f">",
    lambda: Task.CvsCheckout(prefs["</font>cvs<font color="#bc8f8f">"]["</font>cvs<font color="#bc8f8f">"],
                             prefs["</font>cvs<font color="#bc8f8f">"]["</font>workingDirectory<font color="#bc8f8f">"],
                             prefs["</font>cvs<font color="#bc8f8f">"]["</font>root<font color="#bc8f8f">"],
                             prefs["</font>cvs<font color="#bc8f8f">"]["</font>module<font color="#bc8f8f">"],
                             prefs["</font>cvs<font color="#bc8f8f">"]["</font>revision<font color="#bc8f8f">"])),
    ...,
    ("</font>Running NUnit<font color="#bc8f8f">",
    lambda: Task.NUnit(prefs["</font>nunit<font color="#bc8f8f">"]["</font>nunitconsole<font color="#bc8f8f">"],
                       prefs["</font>nunit<font color="#bc8f8f">"]["</font>projectsOrAssemblies<font color="#bc8f8f">"]))
]</font>
</pre>
<p>This example, using the basic concepts of FP such as lists, list comprehension, tuples, build-in functions, and nice syntax, hopefully provided you with a glimpse of how a lot can be achieved in relatively few lines of Python code. Also, if you really want to explore FP from a Python perspective, I suggest you take a look at the <a href="http://sourceforge.net/projects/xoltar-toolkit">Xoltar Toolkit</a> (unfortunately, though, it isn&#8217;t under active development), described in David Mertz&#8217;s columns <a href="http://gnosis.cx/publish/programming/charming_python_16.html">More Functional Programming in Python</a> and <a href="http://gnosis.cx/publish/programming/charming_python_19.html">Even More Functional Programming in Python</a></p>
<p>Bottom line is that the use of FP style in your programs, although it takes time getting use to, leads to fewer lines of code, which leads to fewer places where things can go wrong.</p>
<p>This is not to say that your entire program should be written using the FP style (as is the case with Haskell). However, learning the basic concepts, and how Python exposes these to the developer, you&#8217;ll know which patterns to look for in your code that may be better solved using FP constructs.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bugfree.dk/blog/2006/01/04/being-a-functional-pythonian/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
