<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
    <channel>
        <title>Joe</title>
        <link>http://blog.joelowrance.com/Default.aspx</link>
        <description>Mister Doctor Professor</description>
        <language>en-US</language>
        <copyright>Joe</copyright>
        <generator>Subtext Version 2.1.0.5</generator>
        <image>
            <title>Joe</title>
            <url>http://blog.joelowrance.com/images/RSS2Image.gif</url>
            <link>http://blog.joelowrance.com/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/joelowrance/buGQ" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
            <title>ActiveRecord: could not resolve property</title>
            <link>http://feedproxy.google.com/~r/joelowrance/buGQ/~3/SKwwsm2B0SA/activerecord-could-not-resolve-property.aspx</link>
            <description>&lt;pre class="csharpcode"&gt; &lt;/pre&gt;
&lt;p&gt;Because this has bitten me in the ass more than once.&lt;/p&gt;
&lt;p&gt;When using ActiveRecord to query the database the following error occurs:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;Failed: Castle.ActiveRecord.Framework.ActiveRecordException : Could not perform SlicedFindAll &lt;span class="kwrd"&gt;for&lt;/span&gt; ShoppingCart
  ----&amp;gt; NHibernate.QueryException : could not resolve property: UserId of: MyDomain.Core.ShoppingCart&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Problem&lt;strong&gt;:  &lt;/strong&gt;The Property values in the criteria are case sensitive.&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;&lt;style type="text/css"&gt;&lt;![CDATA[







.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;
&lt;strong&gt;&lt;/strong&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Where the query looks like this: &lt;/p&gt;&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; ShoppingCart LoadCurrentBasket(&lt;span class="kwrd"&gt;string&lt;/span&gt; userId, Guid customerId)
        {
            DetachedCriteria criteria = DetachedCriteria.For&amp;lt;ShoppingCart&amp;gt;();
            criteria.Add(Expression.Eq(&lt;span class="str"&gt;"UserId"&lt;/span&gt;, userId));
            criteria.Add(Expression.Eq(&lt;span class="str"&gt;"CustomerId"&lt;/span&gt;, customerId));

            &lt;span class="kwrd"&gt;return&lt;/span&gt; ActiveRecordMediator&amp;lt;ShoppingCart&amp;gt;.FindFirst(criteria);
        }&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[







.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt; &lt;/p&gt;
&lt;p&gt;And the class looks like this&lt;strong&gt;:&lt;/strong&gt; &lt;/p&gt;&lt;pre class="csharpcode"&gt;    [ActiveRecord(Table = &lt;span class="str"&gt;"Basket"&lt;/span&gt;)]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ShoppingCart
    {
        &lt;span class="kwrd"&gt;private&lt;/span&gt; IList&amp;lt;ShoppingCartItem&amp;gt; _LineItems = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;ShoppingCartItem&amp;gt;();

        [PrimaryKey(PrimaryKeyType.Guid)]
        &lt;span class="kwrd"&gt;public&lt;/span&gt; Guid BasketID { get; set; }

        [Property(&lt;span class="str"&gt;"CustomerId"&lt;/span&gt;)]
        &lt;span class="kwrd"&gt;public&lt;/span&gt; Guid CustomerID { get; set;}

        [Property(&lt;span class="str"&gt;"UserID"&lt;/span&gt;)]
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; UserID { get; set;}

&lt;span class="rem"&gt;///&lt;/span&gt;
&lt;span class="rem"&gt;///&lt;/span&gt;
&lt;span class="rem"&gt;///&lt;/span&gt;

    }&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;&lt;style type="text/css"&gt;&lt;![CDATA[







.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;&lt;img src="http://blog.joelowrance.com/aggbug/32.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/joelowrance/buGQ/~4/SKwwsm2B0SA" height="1" width="1"/&gt;</description>
            <dc:creator>Joe</dc:creator>
            <guid isPermaLink="false">http://blog.joelowrance.com/archive/2008/06/02/activerecord-could-not-resolve-property.aspx</guid>
            <pubDate>Mon, 02 Jun 2008 17:24:52 GMT</pubDate>
            <wfw:comment>http://blog.joelowrance.com/comments/32.aspx</wfw:comment>
            <comments>http://blog.joelowrance.com/archive/2008/06/02/activerecord-could-not-resolve-property.aspx#feedback</comments>
            <wfw:commentRss>http://blog.joelowrance.com/comments/commentRss/32.aspx</wfw:commentRss>
            <trackback:ping>http://blog.joelowrance.com/services/trackbacks/32.aspx</trackback:ping>
        <feedburner:origLink>http://blog.joelowrance.com/archive/2008/06/02/activerecord-could-not-resolve-property.aspx</feedburner:origLink></item>
        <item>
            <title>ExecuteList&amp;lt;T&amp;gt; and ExecuteItem&amp;lt;T&amp;gt;</title>
            <link>http://feedproxy.google.com/~r/joelowrance/buGQ/~3/fd10HAsBK78/executelistlttgt-and-executeitemlttgt.aspx</link>
            <description>&lt;p&gt;In a hand coded data-access layer you often end up with some variant of this pattern when translating a datareader to an entity.&lt;/p&gt;  &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;   &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; List&amp;lt;ICarrier&amp;gt; LoadList()
{    
    List&amp;lt;ICarrier&amp;gt; items = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;ICarrier&amp;gt;();
    &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (SafeDataReader reader = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; AdoHelper().ExecuteDataReader(CommandType.Text, &lt;span style="color: #006080"&gt;"Select * from _lu_Carrier"&lt;/span&gt;))
    {
        &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (reader.Read())
        {
            items.Add(MapCarrier(reader));
        }
    }
    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; items;
}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[








.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;&lt;style type="text/css"&gt;&lt;![CDATA[








.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;
  &lt;br /&gt;where your ADOHelper does whatever it needs to do to connect to the database and run your query.  This is generally coupled with "mapping" method (MapCarrier in this instance) &lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; ICarrier MapCarrier(SafeDataReader dr)
{
    ICarrier carrier = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Carrier();
    carrier.Name = dr.GetString(&lt;span style="color: #006080"&gt;"Name"&lt;/span&gt;);
    carrier.Phone = dr.GetString(&lt;span style="color: #006080"&gt;"Phone"&lt;/span&gt;);
    carrier.SCAC = dr.GetString(&lt;span style="color: #006080"&gt;"SCAC"&lt;/span&gt;);
    carrier.URL = dr.GetString(&lt;span style="color: #006080"&gt;"URL"&lt;/span&gt;);

    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; carrier;
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;I think this is a fairly standard approach, and it works well.  However, it's tedious and can lead to lots of repetition as your DAL grows.  Enter the magic of generics and delegates which allow the code in the first block to become something like this:&lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; List&amp;lt;ICarrier&amp;gt; GetList()
{
    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; AdoHelper().ExecuteList&amp;lt;ICarrier&amp;gt;(CommandType.Text, 
                                                 &lt;span style="color: #006080"&gt;"Select * from _lu_Carrier"&lt;/span&gt;, 
                                                 MapCarrier);
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;ExecuteList&amp;lt;T&amp;gt; is overloaded to allow for a few variations which all route to this:&lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; List&amp;lt;T&amp;gt; ExecuteList&amp;lt;T&amp;gt;(CommandType commandType, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; commandText, Func&amp;lt;T, SafeDataReader&amp;gt; mappingCallback, &lt;span style="color: #0000ff"&gt;params&lt;/span&gt; SqlParameter[] parameters)
{
    List&amp;lt;T&amp;gt; collection = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;T&amp;gt;();
    &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (SafeDataReader reader = ExecuteDataReader(commandType, commandText, parameters))
    {
        &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (reader.Read())
        {
            collection.Add(mappingCallback(reader));
        }
    }
    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; collection;
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The "magic" here is the Func&amp;lt;T SafeDataReader&amp;gt; delegate being passed in.  This is (lifted directly from &lt;a href="http://www.ayende.com/"&gt;Rhino.Commons&lt;/a&gt;) and is declared as&lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;delegate&lt;/span&gt; TResult Func&amp;lt;TResult, S&amp;gt;(S s1);&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;ExecuteItem&amp;lt;T&amp;gt; is similar, but returns a single entity instead of a collection&lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; T ExecuteItem&amp;lt;T&amp;gt;(CommandType commandType, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; commandText, Func&amp;lt;T, SafeDataReader&amp;gt; mappingCallback, &lt;span style="color: #0000ff"&gt;params&lt;/span&gt; SqlParameter[] parameters)
{
    &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (SafeDataReader reader = ExecuteDataReader(commandType, commandText, parameters))
    {
        &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (reader.Read())
        {
            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; mappingCallback(reader);
        }
    }
    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;default&lt;/span&gt;(T);
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Over even a small project this can save a lot of typing and a substantial amount of time.&lt;/p&gt;&lt;img src="http://blog.joelowrance.com/aggbug/31.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/joelowrance/buGQ/~4/fd10HAsBK78" height="1" width="1"/&gt;</description>
            <dc:creator>Joe</dc:creator>
            <guid isPermaLink="false">http://blog.joelowrance.com/archive/2008/01/17/executelistlttgt-and-executeitemlttgt.aspx</guid>
            <pubDate>Thu, 17 Jan 2008 20:08:29 GMT</pubDate>
            <wfw:comment>http://blog.joelowrance.com/comments/31.aspx</wfw:comment>
            <comments>http://blog.joelowrance.com/archive/2008/01/17/executelistlttgt-and-executeitemlttgt.aspx#feedback</comments>
            <wfw:commentRss>http://blog.joelowrance.com/comments/commentRss/31.aspx</wfw:commentRss>
            <trackback:ping>http://blog.joelowrance.com/services/trackbacks/31.aspx</trackback:ping>
        <feedburner:origLink>http://blog.joelowrance.com/archive/2008/01/17/executelistlttgt-and-executeitemlttgt.aspx</feedburner:origLink></item>
        <item>
            <title>Extension Methods and Fluent Interfaces</title>
            <link>http://feedproxy.google.com/~r/joelowrance/buGQ/~3/NVBpxmfUXG4/extension-methods-and-fluent-interfaces.aspx</link>
            <description>&lt;p&gt;File under stupid semantic tricks.&lt;/p&gt;  &lt;p&gt;Extension methods (which seem ripe for abuse and all kinds of bad code) provide some great flexibility when working with fluent interfaces.  For example, take the following extensions to the date class&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ExtensionMethods&lt;/pre&gt;

  &lt;pre&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; IsBefore(&lt;span class="kwrd"&gt;this&lt;/span&gt; DateTime dt, DateTime other)&lt;/pre&gt;

  &lt;pre&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; other &amp;gt; dt;&lt;/pre&gt;

  &lt;pre&gt;        }&lt;/pre&gt;

  &lt;pre class="alt"&gt;    }&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;This allows us to better express our intent &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; WorkingWith&lt;/pre&gt;

  &lt;pre&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Test1()&lt;/pre&gt;

  &lt;pre&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;            DateTime myBirthday = &lt;span class="kwrd"&gt;new&lt;/span&gt; DateTime(2008, 3, 1);&lt;/pre&gt;

  &lt;pre&gt;            DateTime christmans = &lt;span class="kwrd"&gt;new&lt;/span&gt; DateTime(2008, 12,25);&lt;/pre&gt;

  &lt;pre class="alt"&gt;            &lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (myBirthday.IsBefore(christmans))&lt;/pre&gt;

  &lt;pre class="alt"&gt;            {&lt;/pre&gt;

  &lt;pre&gt;                Console.WriteLine(&lt;span class="str"&gt;"yes"&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;            }&lt;/pre&gt;

  &lt;pre&gt; &lt;/pre&gt;

  &lt;pre class="alt"&gt;        }&lt;/pre&gt;

  &lt;pre&gt;    }&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;Which is nice, but can get better by wiring in a call to a utility class&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ExtensionMethods&lt;/pre&gt;

  &lt;pre&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;        ...&lt;/pre&gt;

  &lt;pre&gt; &lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IsBetweenDateRange IsBetween(&lt;span class="kwrd"&gt;this&lt;/span&gt; DateTime dt, DateTime lowDate)&lt;/pre&gt;

  &lt;pre&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; IsBetweenDateRange(dt, lowDate);&lt;/pre&gt;

  &lt;pre&gt;        }&lt;/pre&gt;

  &lt;pre class="alt"&gt;    }&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;which allows a readable (as opposed to parse-then-translate-able) statement such as &lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; voidTest2()&lt;/pre&gt;

  &lt;pre&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;            DateTime myBirthday = &lt;span class="kwrd"&gt;new&lt;/span&gt; DateTime(2008, 3, 1);&lt;/pre&gt;

  &lt;pre&gt;            DateTime halloween = &lt;span class="kwrd"&gt;new&lt;/span&gt; DateTime(2008, 10, 31);&lt;/pre&gt;

  &lt;pre class="alt"&gt;            DateTime christmans = &lt;span class="kwrd"&gt;new&lt;/span&gt; DateTime(2008, 12,25);&lt;/pre&gt;

  &lt;pre&gt;            &lt;/pre&gt;

  &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (halloween.IsBetween(myBirthday).And(christmans))&lt;/pre&gt;

  &lt;pre&gt;            {&lt;/pre&gt;

  &lt;pre class="alt"&gt;                &lt;/pre&gt;

  &lt;pre&gt;            }&lt;/pre&gt;

  &lt;pre class="alt"&gt;        }&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;The utility class in this case being&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; IsBetweenDateRange&lt;/pre&gt;

  &lt;pre&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; DateTime _baseDate;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; DateTime _lowDate;&lt;/pre&gt;

  &lt;pre class="alt"&gt; &lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; IsBetweenDateRange(DateTime baseDate, DateTime lowDate)&lt;/pre&gt;

  &lt;pre class="alt"&gt;        {&lt;/pre&gt;

  &lt;pre&gt;            _baseDate = baseDate;&lt;/pre&gt;

  &lt;pre class="alt"&gt;            _lowDate = lowDate;&lt;/pre&gt;

  &lt;pre&gt;        }&lt;/pre&gt;

  &lt;pre class="alt"&gt; &lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; And(DateTime highDate)&lt;/pre&gt;

  &lt;pre class="alt"&gt;        {&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; _baseDate &amp;gt; _lowDate &amp;amp;&amp;amp; _baseDate &amp;lt; highDate;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        }&lt;/pre&gt;

  &lt;pre&gt; &lt;/pre&gt;

  &lt;pre class="alt"&gt;    }&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;&lt;img src="http://blog.joelowrance.com/aggbug/30.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/joelowrance/buGQ/~4/NVBpxmfUXG4" height="1" width="1"/&gt;</description>
            <dc:creator>Joe</dc:creator>
            <guid isPermaLink="false">http://blog.joelowrance.com/archive/2008/01/10/extension-methods-and-fluent-interfaces.aspx</guid>
            <pubDate>Thu, 10 Jan 2008 13:52:04 GMT</pubDate>
            <wfw:comment>http://blog.joelowrance.com/comments/30.aspx</wfw:comment>
            <comments>http://blog.joelowrance.com/archive/2008/01/10/extension-methods-and-fluent-interfaces.aspx#feedback</comments>
            <wfw:commentRss>http://blog.joelowrance.com/comments/commentRss/30.aspx</wfw:commentRss>
            <trackback:ping>http://blog.joelowrance.com/services/trackbacks/30.aspx</trackback:ping>
        <feedburner:origLink>http://blog.joelowrance.com/archive/2008/01/10/extension-methods-and-fluent-interfaces.aspx</feedburner:origLink></item>
        <item>
            <title>Using Binsor in an Asp.Net Application</title>
            <link>http://feedproxy.google.com/~r/joelowrance/buGQ/~3/t2cs8OcMtok/using-binsor-in-an-asp.net-application.aspx</link>
            <description>&lt;p&gt;This tutorial covers using Binsor2 in an asp.net application.  &lt;/p&gt; &lt;p&gt;Because of different versions and the dearth of information available about getting started with Binsor, I would recommend getting the files listed later in this article directly from the &lt;a href="http://www.ayende.com/projects/rhino-mocks/downloads.aspx"&gt;trunk&lt;/a&gt; as the syntax between versions 1 and 2 has changed.  There is a readme file covering how to build the trunk, and I would add the following points to that:&lt;/p&gt; &lt;p&gt;1.  Run your "Visual Studio Command Line" so that MSBuild is in your path (Start|Programs|Microsoft Visual Studio 200x|Visual Studio Tools) &lt;br /&gt;2.  I had to add a folder called "lib" to "C:\Program Files\Microsoft SDKs\Windows\v6.0A" to get the build to run.&lt;/p&gt; &lt;h4&gt;Getting Started&lt;/h4&gt; &lt;p&gt;Create a new library called BinsorDemo.Domain, and add the following domain entities (fields made public for brevity).&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Account
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; FirstName;
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; LastName;
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; State;
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;decimal&lt;/span&gt; Balance;
        &lt;span class="kwrd"&gt;public&lt;/span&gt; List&amp;lt;Purchase&amp;gt; PurchaseHistory;
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Purchase
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; DateTime Date;
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;decimal&lt;/span&gt; Amount;
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;decimal&lt;/span&gt; AmountDue;

        &lt;span class="kwrd"&gt;public&lt;/span&gt; Purchase(DateTime date, &lt;span class="kwrd"&gt;decimal&lt;/span&gt; amount, &lt;span class="kwrd"&gt;decimal&lt;/span&gt; amountDue)
        {
            Date = date;
            Amount = amount;
            AmountDue = amountDue;
        }
    }&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Next, add the following interfaces.  These are the services that we will "wire-up" using Binsor.&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; ICreditService
    {
        &lt;span class="kwrd"&gt;decimal&lt;/span&gt; GetCreditRemaining(Account c);
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; IInterestCalculator
    {
        &lt;span class="kwrd"&gt;decimal&lt;/span&gt; CalculateInterestOn(Account account);
    }&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;&lt;style type="text/css"&gt;&lt;![CDATA[


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;Finally, add the following concrete implementations of the interfaces.&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CreditService : ICreditService
    {
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;decimal&lt;/span&gt; _CreditLimit;

        &lt;span class="kwrd"&gt;public&lt;/span&gt; CreditService(&lt;span class="kwrd"&gt;decimal&lt;/span&gt; creditLimit)
        {
            _CreditLimit = creditLimit;
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;decimal&lt;/span&gt; GetCreditRemaining(Account account)
        {
            &lt;span class="kwrd"&gt;decimal&lt;/span&gt; totalOutstanding = 0M;
            account.PurchaseHistory.ForEach(&lt;span class="kwrd"&gt;delegate&lt;/span&gt; (Purchase p){totalOutstanding += p.Amount - p.AmountDue;});
            &lt;span class="kwrd"&gt;return&lt;/span&gt; _CreditLimit = totalOutstanding;
        }
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; InterestCalculator : IInterestCalculator
    {
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; &lt;span class="kwrd"&gt;decimal&lt;/span&gt; _InStateAmount;
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; &lt;span class="kwrd"&gt;decimal&lt;/span&gt; _OutOfStateAmount;
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; _ThisState;

        &lt;span class="kwrd"&gt;public&lt;/span&gt; InterestCalculator(&lt;span class="kwrd"&gt;decimal&lt;/span&gt; inStateAmount, &lt;span class="kwrd"&gt;decimal&lt;/span&gt; outOfStateAmount, &lt;span class="kwrd"&gt;string&lt;/span&gt; thisState)
        {
            _InStateAmount = inStateAmount;
            _OutOfStateAmount = outOfStateAmount;
            _ThisState = thisState;
        }

        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;decimal&lt;/span&gt; DetermineInterestRateFor(Account account)
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (account.State.Equals(_ThisState, StringComparison.InvariantCultureIgnoreCase))
                &lt;span class="kwrd"&gt;return&lt;/span&gt; _InStateAmount;
            &lt;span class="kwrd"&gt;else&lt;/span&gt;
                &lt;span class="kwrd"&gt;return&lt;/span&gt; _OutOfStateAmount;
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;decimal&lt;/span&gt; CalculateInterestOn(Account account)
        {
            &lt;span class="kwrd"&gt;decimal&lt;/span&gt; interestRate = DetermineInterestRateFor(account);
            &lt;span class="kwrd"&gt;decimal&lt;/span&gt; interest = 0M;

            account.PurchaseHistory.ForEach(&lt;span class="kwrd"&gt;delegate&lt;/span&gt; (Purchase purchase){interest += purchase.AmountDue*interestRate;});
            &lt;span class="kwrd"&gt;return&lt;/span&gt; interest;
        }
    }&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;h4&gt;Create the Web Application&lt;/h4&gt;
&lt;p&gt;Next create a web application called BinsorDemo.Web.  Add the following references (as mentioned above, I would pull these directly from the trunk - these will be located in [x:\trunk]\rhino-commons\Rhino.Commons\bin\Debug).&lt;/p&gt;
&lt;p&gt;Boo.Lang &lt;br /&gt;Boo.Lang.Compiler &lt;br /&gt;Boo.Lang.Parser &lt;br /&gt;Castle.Core &lt;br /&gt;Castle.Windsor &lt;br /&gt;log4net &lt;br /&gt;Rhino.Commons &lt;br /&gt;BnisorDemo.Domain&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Add a new file to the root of the application called "windsor.boo", and add the following to it.&lt;/p&gt;&lt;pre class="csharpcode"&gt;import BinsorDemo.Domain

creditLimitAmount &lt;span class="kwrd"&gt;as&lt;/span&gt; &lt;span class="kwrd"&gt;decimal&lt;/span&gt; = 500.0

component &lt;span class="str"&gt;'credit_service'&lt;/span&gt;, ICreditService, CreditService:
                        creditLimit=creditLimitAmount


inState &lt;span class="kwrd"&gt;as&lt;/span&gt; &lt;span class="kwrd"&gt;decimal&lt;/span&gt; = .05
outOfState &lt;span class="kwrd"&gt;as&lt;/span&gt; &lt;span class="kwrd"&gt;decimal&lt;/span&gt; = .075
myState = &lt;span class="str"&gt;'MD'&lt;/span&gt;

component &lt;span class="str"&gt;'interest_service'&lt;/span&gt;, IInterestCalculator, InterestCalculator: 
                            inStateAmount = inState
                            outOfStateAmount = outOfState
                            thisState = &lt;span class="str"&gt;"MD"&lt;/span&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Next add a global code file (global.asax), if it is not already there.  Add the following to this file.  The Application_Start event is where the magic takes place.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;&lt;pre class="csharpcode"&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Global : System.Web.HttpApplication
    {
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IWindsorContainer container;

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IWindsorContainer Container
        {
            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; container; }
        }

        &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Application_Start(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)
        {
            XmlConfigurator.Configure();
            &lt;span class="kwrd"&gt;string&lt;/span&gt; binsorConfigFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, &lt;span class="str"&gt;"windsor.boo"&lt;/span&gt;);
            container = &lt;span class="kwrd"&gt;new&lt;/span&gt; WindsorContainer();
            BooReader.Read(container, binsorConfigFilePath);
        }
    }&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;h4&gt;Finally&lt;/h4&gt;
&lt;p&gt;Let's run a quick test to see if everything is working OK.  Add the following to a WebForm's Page_Load event, and navigate to that page.&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Page_Load(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)
        {
            Account demoAccount = &lt;span class="kwrd"&gt;new&lt;/span&gt; Account();
            demoAccount.FirstName = &lt;span class="str"&gt;"Foo"&lt;/span&gt;;
            demoAccount.LastName = &lt;span class="str"&gt;"Bar"&lt;/span&gt;;
            demoAccount.Balance = 250;
            demoAccount.State = &lt;span class="str"&gt;"MD"&lt;/span&gt;;

            demoAccount.PurchaseHistory = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;Purchase&amp;gt;();
            demoAccount.PurchaseHistory.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; Purchase(&lt;span class="kwrd"&gt;new&lt;/span&gt; DateTime(2007, 10, 16), 100M, 15M));
            demoAccount.PurchaseHistory.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; Purchase(&lt;span class="kwrd"&gt;new&lt;/span&gt; DateTime(2007, 11, 16), 10M, 0));
            demoAccount.PurchaseHistory.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; Purchase(&lt;span class="kwrd"&gt;new&lt;/span&gt; DateTime(2007, 12, 16), 250M, 35M));

            Response.Write(Global.Container.Resolve&amp;lt;ICreditService&amp;gt;().GetCreditRemaining(demoAccount));
            Response.Write(&lt;span class="str"&gt;"&amp;lt;hr/&amp;gt;"&lt;/span&gt;);
            Response.Write(Global.Container.Resolve&amp;lt;IInterestCalculator&amp;gt;().CalculateInterestOn(demoAccount));
        }&lt;/pre&gt;&lt;pre class="csharpcode"&gt; &lt;/pre&gt;&lt;img src="http://blog.joelowrance.com/aggbug/29.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/joelowrance/buGQ/~4/t2cs8OcMtok" height="1" width="1"/&gt;</description>
            <dc:creator>Joe</dc:creator>
            <guid isPermaLink="false">http://blog.joelowrance.com/archive/2008/01/08/using-binsor-in-an-asp.net-application.aspx</guid>
            <pubDate>Tue, 08 Jan 2008 17:40:46 GMT</pubDate>
            <wfw:comment>http://blog.joelowrance.com/comments/29.aspx</wfw:comment>
            <comments>http://blog.joelowrance.com/archive/2008/01/08/using-binsor-in-an-asp.net-application.aspx#feedback</comments>
            <wfw:commentRss>http://blog.joelowrance.com/comments/commentRss/29.aspx</wfw:commentRss>
            <trackback:ping>http://blog.joelowrance.com/services/trackbacks/29.aspx</trackback:ping>
        <feedburner:origLink>http://blog.joelowrance.com/archive/2008/01/08/using-binsor-in-an-asp.net-application.aspx</feedburner:origLink></item>
        <item>
            <title>Rhino Mocks Introductory Tutorials</title>
            <link>http://feedproxy.google.com/~r/joelowrance/buGQ/~3/5D-EPF_Vt3U/rhino-mocks-introductory-tutorials.aspx</link>
            <description>&lt;a href="http://www.ayende.com/Wiki/(S(jsaijarncje53cnwhxmjf455))/Introduction+to+Rhino+Mocks.ashx"&gt;Another Introduction to Rhino Mocks &lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.ayende.com/Wiki/(S(jsaijarncje53cnwhxmjf455))/Another+Introduction+To+Rhino+Mocks+Part+II.ashx"&gt;Another Introduction to Rhino Mocks - Part II&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hints id="hah_hints"&gt;&lt;/hints&gt;&lt;img src="http://blog.joelowrance.com/aggbug/27.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/joelowrance/buGQ/~4/5D-EPF_Vt3U" height="1" width="1"/&gt;</description>
            <dc:creator>Joe</dc:creator>
            <guid isPermaLink="false">http://blog.joelowrance.com/archive/2007/12/13/rhino-mocks-introductory-tutorials.aspx</guid>
            <pubDate>Thu, 13 Dec 2007 17:17:23 GMT</pubDate>
            <wfw:comment>http://blog.joelowrance.com/comments/27.aspx</wfw:comment>
            <comments>http://blog.joelowrance.com/archive/2007/12/13/rhino-mocks-introductory-tutorials.aspx#feedback</comments>
            <wfw:commentRss>http://blog.joelowrance.com/comments/commentRss/27.aspx</wfw:commentRss>
            <trackback:ping>http://blog.joelowrance.com/services/trackbacks/27.aspx</trackback:ping>
        <feedburner:origLink>http://blog.joelowrance.com/archive/2007/12/13/rhino-mocks-introductory-tutorials.aspx</feedburner:origLink></item>
        <item>
            <title>lsass.exe Crashes During Login</title>
            <link>http://feedproxy.google.com/~r/joelowrance/buGQ/~3/tZI5dwQnEow/lsass.exe-crashes-during-log-in.aspx</link>
            <description>&lt;p&gt;On HP laptops with the built-in credential manager (fingerprint scanner) running with VMWare (server) running, lsass.exe will crash while logging in telling you that your computer will reboot in 60 seconds.  As documented &lt;a href="http://forums1.itrc.hp.com/service/forums/questionanswer.do?threadId=1173435"&gt;here&lt;/a&gt;, there are a couple of workarounds for this&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Disable the fingerprint scanner  &lt;/li&gt;&lt;li&gt;Set the VMWare services to Manual instead of Automatic (start | run | services.msc)&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Because it's almost 2010 and I want Minority Report style eyeball scanning technology, I settled for number 2 and set following services to Manual.  (they sounded important, and had a circular dependency on each other)&lt;/p&gt; &lt;ul&gt; &lt;li&gt;VMWare Authorization Service [VMAuthdService]  &lt;/li&gt;&lt;li&gt;VMWare Registration Service [VMServerdWin32, RPC Service]&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I left the other 3 services alone as they seemed innocent enough, and had no dependencies.  They were&lt;/p&gt; &lt;ul&gt; &lt;li&gt;VMWare DHCP Service [VMNetDHCP]  &lt;/li&gt;&lt;li&gt;VMWare NAT Service [VMWare NAT Service]  &lt;/li&gt;&lt;li&gt;VMWare Virtual Mount Manager Extended [vmount2]&lt;/li&gt;&lt;/ul&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;Obviously, the services I stopped need to be running for the VMWare application to run, and they do not start without being told to (I was hoping that launching the application would trigger the loading of these).  After verifying that I could start and stop these services from the command line, I added a batch file named VMWareServices to my "Startup" folder with the following commands:&lt;/p&gt; &lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;net start vmauthdservice
net start vmserverdwin32&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;AND IT STILL FAILED&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Next I tried reversing the order these were called in.  This stopped the crash, but for whatever reason vmserverdwin32 did not start.&lt;/p&gt;
&lt;p&gt;I then added a &lt;a href="http://www.robvanderwoude.com/wait.html"&gt;ping delay&lt;/a&gt; delay of 60 seconds.  Still no good.  I could get to the command prompt and type the net start command, and I received the message that the service didn't start in a timely fashion.  Immediately try again and it fires up.  Same results as 120 and 180 seconds.&lt;/p&gt;
&lt;p&gt;&lt;strong title="motherfucker"&gt;@#$*&amp;amp;($*!#^)&amp;amp;%^*^#$^@&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Out of frustration more than anything else, I set the services back to the original order with a 120 second delay and it worked.  Knocked it down to 60 seconds, and it's still good.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SOLUTION&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It's irritating, and it's far from optimal, and I'm not sure why I need the delay, but it does the job.&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;ping 127.0.0.1 -n 60
net start vmauthdservice
net start vmserverdwin32&lt;/pre&gt;&lt;/div&gt;&lt;img src="http://blog.joelowrance.com/aggbug/26.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/joelowrance/buGQ/~4/tZI5dwQnEow" height="1" width="1"/&gt;</description>
            <dc:creator>Joe</dc:creator>
            <guid isPermaLink="false">http://blog.joelowrance.com/archive/2007/11/15/lsass.exe-crashes-during-log-in.aspx</guid>
            <pubDate>Thu, 15 Nov 2007 21:14:05 GMT</pubDate>
            <wfw:comment>http://blog.joelowrance.com/comments/26.aspx</wfw:comment>
            <comments>http://blog.joelowrance.com/archive/2007/11/15/lsass.exe-crashes-during-log-in.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blog.joelowrance.com/comments/commentRss/26.aspx</wfw:commentRss>
            <trackback:ping>http://blog.joelowrance.com/services/trackbacks/26.aspx</trackback:ping>
        <feedburner:origLink>http://blog.joelowrance.com/archive/2007/11/15/lsass.exe-crashes-during-log-in.aspx</feedburner:origLink></item>
        <item>
            <title>Refactoring: From Disaster to Decorator</title>
            <link>http://feedproxy.google.com/~r/joelowrance/buGQ/~3/p1Dj_aV1J3E/refactoring--from-disaster-to-decorator.aspx</link>
            <description>&lt;p&gt; &lt;/p&gt; &lt;p&gt;&lt;img style="margin: 0px 15px 0px 5px" height="400" alt="Messy" src="http://www.joelowrance.com/images/37d561f60fc1_D389/Messy_3.gif" width="200" align="left" /&gt; In &lt;a href="http://www.amazon.com/Working-Effectively-Legacy-Robert-Martin/dp/0131177052/ref=pd_bbs_sr_1/103-1808272-4403012"&gt;Working Effectively with Legacy Code&lt;/a&gt; Michael Feathers describes legacy code as "code without tests".  I describe it as the crap I wrote 4 years ago.  &lt;/p&gt; &lt;p&gt;The code block that I was working with looked like the image to the left.  It was a single method that was 278 lines long, had a cyclomatic complexity of 80 and (according to DevExpress' DXCore) a horrific maintenance complexity of 1766.   The method was used to validate warranty claims and had conditional branching for "Save", "Get Price Details", and "Place".  In addition, the "Get Price Details" and "Place" blocks had conditional statements to handle cases for specific countries.&lt;/p&gt; &lt;p&gt;The first step in refactoring this to something resembling a maintainable state was to extract the method in to it's own WarrantyValidator class.  This meant creating a constructor that accepted all of the variables and fields from the original object that would be required to do the validation.  In this case I needed the Warranty Claim being validated, the user's country, a list to store the failure messages in (a discussion for another day) and the number of items on the claim. &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;The end result is a class that looked like this (&lt;em&gt;this is "blog" code)&lt;/em&gt;&lt;/p&gt; &lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ValidateClaim
    {
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; WarrantyClaim ClaimToValidate;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; NumberOfItemsOnClaim;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; CountryCode;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; List&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; ErrorCodes;


        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ValidateClaim(WarrantyClaim claimToValidate, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; numberOfItemsOnClaim, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; countryCode, List&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; errorCodes)
        {
            ClaimToValidate = claimToValidate;
            NumberOfItemsOnClaim = numberOfItemsOnClaim;
            CountryCode = countryCode;
            ErrorCodes = errorCodes;
        }


        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; Validate(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ActionName)
        {
            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (ActionName == &lt;span style="color: #006080"&gt;"SAVE"&lt;/span&gt;)
            {
                &lt;span style="color: #008000"&gt;//save-specific validation for example&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(ClaimToValidate.AuthorizationNumber))
                {
                    ErrorCodes.Add(&lt;span style="color: #006080"&gt;"12345678-1234-1234-123456789012"&lt;/span&gt;);
                }
            }
            &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (ActionName == &lt;span style="color: #006080"&gt;"PRICE"&lt;/span&gt;)
            {
                &lt;span style="color: #008000"&gt;//pricing-specifi validation&lt;/span&gt;
                
                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (CountryCode == &lt;span style="color: #006080"&gt;"US"&lt;/span&gt;)
                {
                    &lt;span style="color: #008000"&gt;//us specific validation&lt;/span&gt;
                }
                &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (CountryCode == &lt;span style="color: #006080"&gt;"GB"&lt;/span&gt;)
                {
                    &lt;span style="color: #008000"&gt;//gb specific valudation&lt;/span&gt;
                }
            }
            &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (ActionName == &lt;span style="color: #006080"&gt;"PLACE"&lt;/span&gt;)
            {
                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (CountryCode == &lt;span style="color: #006080"&gt;"US"&lt;/span&gt;)
                {
                    &lt;span style="color: #008000"&gt;//us specific validation&lt;/span&gt;
                }
                &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (CountryCode == &lt;span style="color: #006080"&gt;"GB"&lt;/span&gt;)
                {
                    &lt;span style="color: #008000"&gt;//gb specific valudation&lt;/span&gt;
                }
            }

            &lt;span style="color: #008000"&gt;/*&lt;/span&gt;
&lt;span style="color: #008000"&gt;             * lots of validation no matter what the action is&lt;/span&gt;
&lt;span style="color: #008000"&gt;             * ...&lt;/span&gt;
&lt;span style="color: #008000"&gt;             * ...&lt;/span&gt;
&lt;span style="color: #008000"&gt;             * ...&lt;/span&gt;
&lt;span style="color: #008000"&gt;             */&lt;/span&gt;

            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; ErrorCodes.Count == 0;
        }
    }&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;The next step (which I guess probably should have been the first) was generate tests to cover as much code as possible.  In doing this I found that I needed a couple of additional parameters in my constructor as data that was exposed through the properties of the WarrantyClaim wasn't available without banging against the database.  At the end of this phase, I had managed to get about 95% test coverage, and some analysis of the WarrantyClaim suggested that a couple of cases for which validation code existed were no longer possible.  With 76 "green" tests I began breaking up the object and re-running the tests for verification after every change.&lt;/p&gt;
&lt;p&gt;The first change was to create the WarrantyValidatorBase.  This abstract class contained a constructor identical to my WarrantyValidator class and an abstract method called Validate.  &lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;abstract&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; WarrantyValidatorBase
{
    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; WarrantyClaim ClaimToValidate;
    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; NumberOfItemsOnClaim;
    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; CountryCode;
    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; List&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; ErrorCodes;

    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; WarrantyValidatorBase(WarrantyClaim claimToValidate, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; numberOfItemsOnClaim, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; countryCode, List&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; errorCodes)
    {
        ClaimToValidate = claimToValidate;
        NumberOfItemsOnClaim = numberOfItemsOnClaim;
        CountryCode = countryCode;
        ErrorCodes = errorCodes;
    }

    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;abstract&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Validate();
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;From here I moved all of the Save validation to it's own class, and repeated this with the Price Details and Place validation.  Next, I extracted the country specific validation into separate classes - WarrantyPlaceValidationUS, WarrantyPlaceValidationGB, etc.    &lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; WarrantyPlaceValidator : WarrantyValidatorBase
    {
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; WarrantyPlaceValidator(WarrantyClaimWarrantyClaim claimToValidate, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; numberOfItemsOnClaim, 
                                        &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; countryCode, List&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; errorCodes) 
            : &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;(claimToValidate, numberOfItemsOnClaim, countryCode, errorCodes)
        {
        }


        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Validate()
        {
            &lt;span style="color: #008000"&gt;//place specific validation&lt;/span&gt;

            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (CountryCode == &lt;span style="color: #006080"&gt;"US"&lt;/span&gt;)
            {
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; WarrantyPlaceValidatorUS(ClaimToValidate, NumberOfItemsOnClaim, CountryCode, ErrorCodes).Validate();
            }
            &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (CountryCode == &lt;span style="color: #006080"&gt;"GB"&lt;/span&gt;)
            {
                &lt;span style="color: #008000"&gt;//gb specific valudation&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; WarrantyPlaceValidatorGB(ClaimToValidate, NumberOfItemsOnClaim, CountryCode, ErrorCodes).Validate();
            }
        }
    }


    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; WarrantyPlaceValidatorUS : WarrantyValidatorBase
    {
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; WarrantyPlaceValidatorUS(WarrantyClaim claimToValidate, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; numberOfItemsOnClaim,
                                        &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; countryCode, List&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; errorCodes)
            : &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;(claimToValidate, numberOfItemsOnClaim, countryCode, errorCodes)
        {
        }


        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Validate()
        {
            &lt;span style="color: #008000"&gt;//us specific validation&lt;/span&gt;
        }
    }


    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; WarrantyPlaceValidatorGB : WarrantyValidatorBase
    {
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; WarrantyPlaceValidatorGB(WarrantyClaimclaimToValidate, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; numberOfItemsOnClaim,
                                        &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; countryCode, List&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; errorCodes)
            : &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;(claimToValidate, numberOfItemsOnClaim, countryCode, errorCodes)
        {
        }


        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Validate()
        {
            &lt;span style="color: #008000"&gt;//GB specific validation&lt;/span&gt;
        }
    }&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;After this refactoring, my original diagram looked a little like this: &lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.joelowrance.com/images/37d561f60fc1_D389/BrokenUp2.jpg" atomicselection="true"&gt;&lt;img height="100" alt="BrokenUp2" src="http://www.joelowrance.com/images/37d561f60fc1_D389/BrokenUp2_thumb.jpg" width="400" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Again, after each change, I re-ran my tests and made sure that everything was still ok. &lt;/p&gt;
&lt;p&gt;So far, so good.  The new code was a far easier to maintain than the previous approach.  I now had small testable classes, which were easy to read and instantly understandable.  They all had very specific purposes and were very loosely coupled.  However, there was still an awful lot of duplication in the constructors, and I was not happy with the country specific cases being handled this way.  &lt;/p&gt;
&lt;p&gt;I knew this needed to be resolved, but I was a little stuck.  I am pretty clueless when it comes to design patterns and to be perfectly honest, the GoF book makes me want to gouge my eyes out.  Fortunately, the &lt;a href="http://www.amazon.com/Head-First-Design-Patterns/dp/0596007124/ref=pd_bbs_sr_1/103-1808272-4403012?ie=UTF8&amp;amp;s=books&amp;amp;qid=1193860244&amp;amp;sr=1-1"&gt;Head First book&lt;/a&gt; and Alex Henderson's &lt;a href="http://blog.bittercoder.com/PermaLink,guid,4863e460-2985-475c-9266-80b4895e80de.aspx"&gt;Windsor tutorial&lt;/a&gt; gave me a little insight into the &lt;a href="http://www.dofactory.com/Patterns/PatternDecorator.aspx"&gt;Decorator&lt;/a&gt; pattern.  Time for some more refactoring...&lt;/p&gt;
&lt;p&gt;The WarrantyValidatorBase ended up looking like this.&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;abstract&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; WarrantyValidatorBase
    {

        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; List&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; _ErrorPhrases;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; WarrantyClaim _WarrantyClaim;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; WarrantyValidatorBase _ChildValidator;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; _NumberOfPartsInBasket;

        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; WarrantyValidatorBase()
        {
        }

        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; WarrantyValidatorBase(WarrantyValidatorBase decorateWith)
        {
            _ChildValidator = decorateWith;
        }

        &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; AddErrorId(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; errorGuid)
        {
            _ErrorPhrases.Add(errorGuid);
        }

        &lt;span style="color: #0000ff"&gt;internal&lt;/span&gt; ToolCommerce.Warranty WarrantyClaim
        {
            get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _WarrantyClaim; }
            set { _WarrantyClaim = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }
        }

        &lt;span style="color: #0000ff"&gt;internal&lt;/span&gt; List&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; Phrases
        {
            get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _ErrorPhrases; }
            set { _ErrorPhrases = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }
        }

        &lt;span style="color: #0000ff"&gt;internal&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; NumberOfPartsInBasket
        {
            get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _NumberOfPartsInBasket; }
            set { _NumberOfPartsInBasket = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }
        }

        &lt;span style="color: #0000ff"&gt;internal&lt;/span&gt; WarrantyValidatorBase ChildValidator
        {
            get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _ChildValidator; }
            set { _ChildValidator = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }
        }


        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;abstract&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Validate();

        &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ValidateChild()
        {

            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (_ChildValidator!=&lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
            {
                _ChildValidator.Phrases = _ErrorPhrases;
                _ChildValidator.WarrantyClaim = _WarrantyClaim;
                _ChildValidator.NumberOfPartsInBasket = _NumberOfPartsInBasket;
                _ChildValidator.Validate();
            }
        }

    }&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Note the addition of the _ChildValidator field and the constructor changes to accept another object deriving from WarrantyValidatorBase.  I also moved the arguments from the constructor to properties - this just seemed a little cleaner to me.  The ValidateChild method is key here.  It passes the validation request down the "decorator chain" to its ChildValidator, and its ChildValidator to &lt;em&gt;its&lt;/em&gt; ChildValidator and so on.  This approach allowed me to change my WarrantyPlaceValidator to this:&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; WarrantyPlaceValidator : WarrantyValidatorBase
{
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; WarrantyPlaceValidator(WarrantyValidatorBase childValidation)
    {
        ChildValidator = childValidation;
    }

    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Validate()
    {
        &lt;span style="color: #008000"&gt;//place specific validation&lt;/span&gt;
        &lt;span style="color: #008000"&gt;//notice that there is nothing specific to countries in here any more&lt;/span&gt;
        ValidateChild();
    }
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;End Result&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The awesomeness of the decorator is that I can chain these together and add functionality without having to clutter up my classes with conditionals and branching logic.&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ValidateForPlace(Warranty claimToValidate, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; numberOfItemsOnClaim, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; countryCode, List&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; errorCodes)
{
    WarrantyValidatorBase validator = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;

    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (countryCode == &lt;span style="color: #006080"&gt;"US"&lt;/span&gt;)
    {
        validator = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; WarrantyValidator(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; WarrantyPlaceValidator(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; WarrantyPlaceValidatorUS()));
    }
    &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (countryCode == &lt;span style="color: #006080"&gt;"GB"&lt;/span&gt;)
    {
        validator = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; WarrantyValidator(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; WarrantyPlaceValidator(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; WarrantyPlaceValidatorGB()));
    }
    &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
    {
        &lt;span style="color: #008000"&gt;//no country specific validation&lt;/span&gt;
        validator = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; WarrantyValidator(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; WarrantyPlaceValidator());
    }

    validator.NumberOfPartsInBasket = numberOfItemsOnClaim;
    validator.Phrases = errorCodes;
    validator.WarrantyClaim = claimToValidate;
    validator.Validate();
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;If new functionality is required, it can be encapsulated and then "chained" in.&lt;/p&gt;&lt;img src="http://blog.joelowrance.com/aggbug/25.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/joelowrance/buGQ/~4/p1Dj_aV1J3E" height="1" width="1"/&gt;</description>
            <dc:creator>Joe</dc:creator>
            <guid isPermaLink="false">http://blog.joelowrance.com/archive/2007/10/31/refactoring--from-disaster-to-decorator.aspx</guid>
            <pubDate>Wed, 31 Oct 2007 20:01:09 GMT</pubDate>
            <wfw:comment>http://blog.joelowrance.com/comments/25.aspx</wfw:comment>
            <comments>http://blog.joelowrance.com/archive/2007/10/31/refactoring--from-disaster-to-decorator.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://blog.joelowrance.com/comments/commentRss/25.aspx</wfw:commentRss>
            <trackback:ping>http://blog.joelowrance.com/services/trackbacks/25.aspx</trackback:ping>
        <feedburner:origLink>http://blog.joelowrance.com/archive/2007/10/31/refactoring--from-disaster-to-decorator.aspx</feedburner:origLink></item>
        <item>
            <title>Unable to create a manifest resource name for ...</title>
            <link>http://feedproxy.google.com/~r/joelowrance/buGQ/~3/2PLnseO1I-o/unable-to-create-a-manifest-resource-name-for.aspx</link>
            <description>&lt;p&gt;In case I run into this again...&lt;/p&gt; &lt;p&gt;During a build for a .net solution using Team Foundation Server, we got an error that said.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;error MSB3041: Unable to create a manifest resource name for "NewService\WarrantyUpload.aspx.resx". Could not find a part of the path 'E:\Builds\My App\Source\Code\MyApp.WebApp\Folder\File.aspx.vb'.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;What had happened was that \Folder had been accidentally dragged and dropped into another folder.&lt;/p&gt;&lt;img src="http://blog.joelowrance.com/aggbug/24.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/joelowrance/buGQ/~4/2PLnseO1I-o" height="1" width="1"/&gt;</description>
            <dc:creator>Joe</dc:creator>
            <guid isPermaLink="false">http://blog.joelowrance.com/archive/2007/10/15/unable-to-create-a-manifest-resource-name-for.aspx</guid>
            <pubDate>Mon, 15 Oct 2007 20:20:13 GMT</pubDate>
            <wfw:comment>http://blog.joelowrance.com/comments/24.aspx</wfw:comment>
            <comments>http://blog.joelowrance.com/archive/2007/10/15/unable-to-create-a-manifest-resource-name-for.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://blog.joelowrance.com/comments/commentRss/24.aspx</wfw:commentRss>
            <trackback:ping>http://blog.joelowrance.com/services/trackbacks/24.aspx</trackback:ping>
        <feedburner:origLink>http://blog.joelowrance.com/archive/2007/10/15/unable-to-create-a-manifest-resource-name-for.aspx</feedburner:origLink></item>
        <item>
            <title>Fluent Interface Take 2</title>
            <link>http://feedproxy.google.com/~r/joelowrance/buGQ/~3/vDcitN1Oqxs/fluent-interface-take-2.aspx</link>
            <description>&lt;p&gt; &lt;/p&gt; &lt;p&gt;Where this is code that is duplicated all over the place with only minor alterations for the data source and the default value:&lt;/p&gt; &lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;DropDownList cbo = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DropDownList();
cbo.DataSource = PersonMotherObject.GetPersons();
cbo.DataTextField = &lt;span style="color: #006080"&gt;"FirstName"&lt;/span&gt;;
cbo.DataValueField = &lt;span style="color: #006080"&gt;"LastCommaFirst"&lt;/span&gt;;
cbo.DataBind();

cbo.Items.Insert(0, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ListItem(&lt;span style="color: #006080"&gt;""&lt;/span&gt;, &lt;span style="color: #006080"&gt;"----- SELECT -----"&lt;/span&gt;));

&lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (ListItem listItem &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; cbo.Items)
{
    listItem.Selected = listItem.Value == &lt;span style="color: #006080"&gt;"Flanders, Ned"&lt;/span&gt;;
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;This reads a lot easier, and gets us a little more DRY:&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ComboBoxSetter&amp;lt;Person&amp;gt;()
                .WithListControl(ddl)
                .WithDataSourceOf(PersonMotherObject.GetPersons())
                .SetSelectedWhereTextIs(&lt;span style="color: #006080"&gt;"Ned"&lt;/span&gt;)
                .AddLeadingItemOf(&lt;span style="color: #006080"&gt;""&lt;/span&gt;, &lt;span style="color: #006080"&gt;"-----Select------"&lt;/span&gt;)
                .TheDataTextFieldIs(&lt;span style="color: #006080"&gt;"FirstName"&lt;/span&gt;)
                .TheDataValueFieldIs(&lt;span style="color: #006080"&gt;"LastCommaFirst"&lt;/span&gt;)
                .Bind();&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;The class that does the grunt work (reformatted for brevity)&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #008000"&gt;/// Provides a fluent interface for setting a combo box&lt;/span&gt;
&lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ComboBoxSetter&amp;lt;T&amp;gt;
{
    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; ListControl Control;
    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; IList&amp;lt;T&amp;gt; DataSource;
    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; DefaultValue;
    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; ListItem ListItemToAdd;
    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; DataValueField;
    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; DataTextField;

    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Bind()
    {
        Control.DataSource = DataSource;
        Control.DataTextField = DataTextField;
        Control.DataValueField = DataValueField;
        Control.DataBind();

        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (ListItemToAdd != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
            Control.Items.Insert(0, ListItemToAdd);

        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(DefaultValue))
            &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (ListItem listItem &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; Control.Items)
                listItem.Selected = listItem.Text == DefaultValue;
    }


    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ComboBoxSetter&amp;lt;T&amp;gt; WithListControl(ListControl ddl)
    {
        Control = ddl;
        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;;
    }

    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ComboBoxSetter&amp;lt;T&amp;gt; WithDataSourceOf(IList&amp;lt;T&amp;gt; people)
    {
        DataSource = people;
        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;;
    }

    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ComboBoxSetter&amp;lt;T&amp;gt; SetSelectedWhereTextIs(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; defaultSelection)
    {
        DefaultValue = defaultSelection;
        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;;
    }

    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ComboBoxSetter&amp;lt;T&amp;gt; AddLeadingItemOf(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; display)
    {
        ListItemToAdd = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ListItem(display, &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;);
        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;;
    }

    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ComboBoxSetter&amp;lt;T&amp;gt; AddLeadingItemOf(ListItem leadingItem)
    {
        ListItemToAdd = leadingItem;
        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;;
    }

    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ComboBoxSetter&amp;lt;T&amp;gt; TheDataValueFieldIs(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; dataValueField)
    {
        DataValueField = dataValueField;
        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;;
        
    }

    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ComboBoxSetter&amp;lt;T&amp;gt; TheDataTextFieldIs(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; dataTextField)
    {
        DataTextField = dataTextField;
        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;;
    }
&lt;/pre&gt;&lt;/div&gt;&lt;img src="http://blog.joelowrance.com/aggbug/20.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/joelowrance/buGQ/~4/vDcitN1Oqxs" height="1" width="1"/&gt;</description>
            <dc:creator>Joe</dc:creator>
            <guid isPermaLink="false">http://blog.joelowrance.com/archive/2007/09/20/fluent-interface-take-2.aspx</guid>
            <pubDate>Fri, 21 Sep 2007 01:42:30 GMT</pubDate>
            <wfw:comment>http://blog.joelowrance.com/comments/20.aspx</wfw:comment>
            <comments>http://blog.joelowrance.com/archive/2007/09/20/fluent-interface-take-2.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blog.joelowrance.com/comments/commentRss/20.aspx</wfw:commentRss>
            <trackback:ping>http://blog.joelowrance.com/services/trackbacks/20.aspx</trackback:ping>
        <feedburner:origLink>http://blog.joelowrance.com/archive/2007/09/20/fluent-interface-take-2.aspx</feedburner:origLink></item>
        <item>
            <title>HTTP Cache Helper With a Fluent Interface</title>
            <link>http://feedproxy.google.com/~r/joelowrance/buGQ/~3/Bm3gMa9lzzk/http-cache-helper-with-a-fluent-interface.aspx</link>
            <description>&lt;p&gt;After writing the same 20 lines of boilerplate code for the 1000th time, I decided to encapsulate it in a class and add some syntactic sweetness to it in the form of a fluent interface as recently demonstrated by &lt;a href="http://joeydotnet.com/blog/archive/2007/09/06/Refactoring-towards-a-DRY-fluent-interface.aspx"&gt;Joey Beninghove&lt;/a&gt;.  &lt;/p&gt; &lt;p&gt;What I had been doing was something like the following pseudocode (or a slight variation) in every place I wanted to cache something.&lt;/p&gt; &lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;declare returnObject as null

if the HTTPCache available
    if the object is available in the cache
        set returnObject
    else
        set returnObject to whatever code is needed to get the object
        add returnObject to the cache
else
  set returnObject to whatever code is needed to get the object

return returnObject  
        
   
    &lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Here is the class I ended up with.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; HTTPCacheHelper&amp;lt;T&amp;gt;
 {
     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; DateTime? _AbsoluteExpiration;
     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; TimeSpan? _SlidingExpiration;
     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; CacheItemPriority _Priority = CacheItemPriority.Default;
     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; _Key;

     &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
     &lt;span style="color: #008000"&gt;/// Key of item stored in the cache.&lt;/span&gt;
     &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; HTTPCacheHelper&amp;lt;T&amp;gt; WithKeyOf(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; key)
     {
         _Key = key;
         &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;;
     }

     &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
     &lt;span style="color: #008000"&gt;/// Absolute date to expire on&lt;/span&gt;
     &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
     &lt;span style="color: #008000"&gt;/// &amp;lt;remarks&amp;gt;&lt;/span&gt;
     &lt;span style="color: #008000"&gt;/// Optional, but either this or WithSlidingExpiration must be called&lt;/span&gt;
     &lt;span style="color: #008000"&gt;/// &amp;lt;/remarks&amp;gt;&lt;/span&gt;
     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; HTTPCacheHelper&amp;lt;T&amp;gt; WithExpirationDateOf(DateTime expires)
     {
         _AbsoluteExpiration = expires;
         &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;;
     }

     &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
     &lt;span style="color: #008000"&gt;/// Sliding timespan to expire on.&lt;/span&gt;
     &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
     &lt;span style="color: #008000"&gt;/// &amp;lt;remarks&amp;gt;&lt;/span&gt;
     &lt;span style="color: #008000"&gt;/// Optional, but either this or WithExpirationDateOf must be called&lt;/span&gt;
     &lt;span style="color: #008000"&gt;/// &amp;lt;/remarks&amp;gt;&lt;/span&gt;
     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; HTTPCacheHelper&amp;lt;T&amp;gt; WithSlidingExpiration(TimeSpan ts)
     {
         _SlidingExpiration = ts;
         &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;;
     }

     &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
     &lt;span style="color: #008000"&gt;/// Priority&lt;/span&gt;
     &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; HTTPCacheHelper&amp;lt;T&amp;gt; WithPriorityOf(CacheItemPriority priority)
     {
         _Priority = priority;
         &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;;
     }

     &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
     &lt;span style="color: #008000"&gt;/// Adds the item to the cache based data passed in in previous methods.  &lt;/span&gt;
     &lt;span style="color: #008000"&gt;/// This will the last method call in the chain, and must&lt;/span&gt;
     &lt;span style="color: #008000"&gt;/// be called in order to for the item to be cached.&lt;/span&gt;
     &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Commit(T item)
     {
         Debug.Assert(!item.Equals(&lt;span style="color: #0000ff"&gt;default&lt;/span&gt;(T)));
         Debug.Assert(!_AbsoluteExpiration.HasValue ^ _SlidingExpiration.HasValue);
         Debug.Assert(!&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(_Key));

         &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!_AbsoluteExpiration.HasValue) _AbsoluteExpiration = Cache.NoAbsoluteExpiration;
         &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!_SlidingExpiration.HasValue) _SlidingExpiration = Cache.NoSlidingExpiration;

         &lt;span style="color: #0000ff"&gt;lock&lt;/span&gt; (HttpRuntime.Cache)
         {
             HttpRuntime.Cache.Add(_Key, item, &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;, _AbsoluteExpiration.Value, _SlidingExpiration.Value, _Priority, &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;);
         }
     }


     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt;  T GetItem(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; key)
     {
         &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (HttpRuntime.Cache != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
         {
             &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; check = HttpRuntime.Cache[key];

             &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (check != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
             {
                 &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; (T)check;
             }
         }

         &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;default&lt;/span&gt;(T);
     }

     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; IsNull(T item)
     {
         &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(T).IsValueType)
         {
             &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;default&lt;/span&gt;(T).Equals(item);
         }
         &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
         {
             &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; item == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
         }

     }


     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt;  T GetItem(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; key, Func&amp;lt;T&amp;gt; itemSourceOnDoesNotExist)
     {
         T check = GetItem(key);

         &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (IsNull(check))
         {
             check = itemSourceOnDoesNotExist();
         }

         &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; check;
     }

     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt;  T GetItem(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; key, Func&amp;lt;T&amp;gt; itemSourceOnDoesNotExist, Proc&amp;lt;T&amp;gt; addToCache)
     {
         T check = GetItem(key);

         &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (IsNull(check))
         {
             check = itemSourceOnDoesNotExist();
             addToCache(check);
         }
         &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; check;
     }
     
 }
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;The methods prior to Commit() make up the fluent interface, and I stole a little code from &lt;a href="http://blog.ayende.com"&gt;Ayende&lt;/a&gt;'s Rhino Commons for the delegates in the GetItem methods.  As a side note, the GetItems methods were originally static, which allowed me to do the following: &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ItemToCache()
{
    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #006080"&gt;"expected value"&lt;/span&gt;;
}


[Test]
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; FluentSyntaxText()
{
    HTTPCacheHelper&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; cache = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; HTTPCacheHelper&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;();

    cache
        .WithExpirationDateOf(DateTime.Now.AddDays(1))
        .WithKeyOf(&lt;span style="color: #006080"&gt;"TestKey"&lt;/span&gt;)
        .WithPriorityOf(CacheItemPriority.Low)
        .Commit(ItemToCache());

    &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; actualValue = HTTPCacheHelper&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;.GetItem(&lt;span style="color: #006080"&gt;"TestKey"&lt;/span&gt;, ItemToCache, cache.Commit);

    Assert.AreEqual(&lt;span style="color: #006080"&gt;"expected value"&lt;/span&gt;, actualValue);

}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;But it dawned on me a little later that by making them instance methods I could accomplish the same thing in a single statement &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;[Test] 
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; FluentSyntaxTest2()
{
    HTTPCacheHelper&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; cache = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; HTTPCacheHelper&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;();

    &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; actualValue = cache
        .WithExpirationDateOf(DateTime.Now.AddDays(1))
        .WithKeyOf(&lt;span style="color: #006080"&gt;"TestKey"&lt;/span&gt;)
        .WithPriorityOf(CacheItemPriority.Low)
        .GetItem(&lt;span style="color: #006080"&gt;"TestKey"&lt;/span&gt;, ItemToCache, cache.Commit);

    Assert.AreEqual(&lt;span style="color: #006080"&gt;"expected value"&lt;/span&gt;, actualValue);

}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Which is pretty friggin' sweet.&lt;/p&gt;&lt;img src="http://blog.joelowrance.com/aggbug/19.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/joelowrance/buGQ/~4/Bm3gMa9lzzk" height="1" width="1"/&gt;</description>
            <dc:creator>Joe</dc:creator>
            <guid isPermaLink="false">http://blog.joelowrance.com/archive/2007/09/13/http-cache-helper-with-a-fluent-interface.aspx</guid>
            <pubDate>Fri, 14 Sep 2007 03:43:29 GMT</pubDate>
            <wfw:comment>http://blog.joelowrance.com/comments/19.aspx</wfw:comment>
            <comments>http://blog.joelowrance.com/archive/2007/09/13/http-cache-helper-with-a-fluent-interface.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blog.joelowrance.com/comments/commentRss/19.aspx</wfw:commentRss>
            <trackback:ping>http://blog.joelowrance.com/services/trackbacks/19.aspx</trackback:ping>
        <feedburner:origLink>http://blog.joelowrance.com/archive/2007/09/13/http-cache-helper-with-a-fluent-interface.aspx</feedburner:origLink></item>
    </channel>
</rss>
