<rss version="2.0" 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/">
    <channel>
        <title>StrangeLog - The (english) blog of Andrea Saltarello</title>
        <link>http://blogs.ugidotnet.org/mrbrightside/Default.aspx</link>
        <description>Life in the so-called space age</description>
        <language>en-US</language>
        <copyright>Andrea Saltarello</copyright>
        <generator>Subtext Version 2.6.0.0</generator>
        <image>
            <title>StrangeLog - The (english) blog of Andrea Saltarello</title>
            <url>http://blogs.ugidotnet.org/images/RSS2Image.gif</url>
            <link>http://blogs.ugidotnet.org/mrbrightside/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <item>
            <title>No, NSK is not (about) Northwind</title>
            <category>Software Architecture</category>
            <category>NSK</category>
            <link>http://blogs.ugidotnet.org/mrbrightside/archive/2012/01/10/no-nsk-is-not-about-northwind.aspx</link>
            <description>&lt;p&gt;So it seems my &lt;a href="http://nsk.codeplex.com/"&gt;pet project&lt;/a&gt; &lt;a href="http://goo.gl/W3GQc"&gt;has been Ayende-ified&lt;/a&gt;; Oren has been so kind to let me have a preview at his posts and that urged me to talk a bit about what NSK is and what it is aimed for.&lt;/p&gt;  &lt;p&gt;I started NSK in 2004 in order to have a “one size fits all” demo for the talks and classes I and my colleagues at &lt;a href="http://www.manageddesigns.it/"&gt;Managed Designs&lt;/a&gt; were holding; all I wanted was a way to showcase topics such as:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;How an O/RM works (Unit of Work, proxies, queries &amp;amp; fetch plan management, …) &lt;/li&gt;    &lt;li&gt;How to implement common presentation design patterns (MVC, MVP, …) &lt;/li&gt;    &lt;li&gt;How to unit test code &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Other than having that demo, I also wanted to make everyone able to have it up &amp;amp; running as frictionless as possible, so I:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Made it open source (choosing IBM’s OSI-approved Common Public License) and &lt;a href="http://sourceforge.net/projects/nsk/files/"&gt;downloadable from Sourgeforge&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Had it use the “ubiquitous” Northwind database &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I knew from the start that such a db would have impaired my ability to design an effective &lt;strong&gt;Domain Model&lt;/strong&gt;, but I didn’t care ‘cause that was code that I was expected to show (and comment), and not targeted to the casual downloader. &lt;/p&gt;  &lt;p&gt;Let’s just have an example: in order to allow me to explain how an O/RM works and avoid early adopters (remember, we are talking about year 2004/2005) fear for “O/RMs black magic”, I defined both a &lt;strong&gt;IUnitOfWork&lt;/strong&gt; interface and my own &lt;em&gt;query object&lt;/em&gt;, and then implemented both delegating the real work to &lt;strong&gt;NHibernate&lt;/strong&gt;. I even implemented proxies for a couple of entities in order to show how O/RMs manage concurrency. Frankly, I did not pay much attention to my implementation of UoW/query object/proxies, because that implementation wasn’t neither expected to go live in a “production” system nor looked at as an advice to encapsulate an O/RM. That “poor man’s” O/RM, let me stress about that, was only meant to allow me to talk about how an O/RMs works without having to resort to NHibernate source, which IMHO would have been overkill. And when &lt;strike&gt;DLINQ&lt;/strike&gt; &lt;strong&gt;Linq 2 SQL&lt;/strong&gt; came to us, I renamed the &lt;strong&gt;IUnitOfWork&lt;/strong&gt; interface to &lt;strong&gt;IDataContext&lt;/strong&gt; in order to better adhere to .NET’s emerging jargon: again, I was only trying to have a “companion demo” which fitted my own presenting needs so, when the “pioneering era of O/RM” relating to the .NET community ended (which, IMHO, happened with Microsoft releasing L2SQL and then EF) I considered my “introduce O/RMs by explaining the inner workings” strategy obsolete, made a branch for those still interested in having a look to that code and had NSK switched to the LINQ side of the Force.&lt;/p&gt;  &lt;p&gt;And then came the &lt;a href="http://goo.gl/58173"&gt;book&lt;/a&gt; (to which, BTW, both me and &lt;a href="http://weblogs.asp.net/despos/"&gt;Dino&lt;/a&gt; refer to as “the brick” &amp;lt;g&amp;gt;): we needed a companion demo, and ultimately chose to use NSK so I had to fit into the codebase a bunch of samples covering nearly all the book’s topics, such as:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The book talks about IoC and unit testing, so I ended implementing custom factories for both ASP.NET MVC (which at the time was in the “v1 beta” timeframe) and WCF in order to inject dependencies and/or mock objects &lt;/li&gt;    &lt;li&gt;the book talks about validation and we wanted to show the capabilities of Enterprise Library’s Validation Application Block (which I still think is pretty gorgeous), so I did put in demos using both the custom attributes and the xml rulesets to validate the domain model &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Again, the codebase was intended to be looked at while being guided by the book and not as a fully fledged application (please note that NSK &lt;a href="http://nsk.codeplex.com/releases"&gt;still does not sport a release&lt;/a&gt;) or as an example of how to implement a Domain Model. If you look to NSK this way, you will find a lot of thing you would do very differently in a “real” application. Just to make an example: you have a look at the &lt;strong&gt;CalculateTotalIncome()&lt;/strong&gt; method of the &lt;strong&gt;Customer&lt;/strong&gt; class and find the following, pretty sub-optimal, code:&lt;/p&gt;  &lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt; CalculateTotalIncome()&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt;     Contract.Ensures(Contract.Result&amp;lt;&lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;&amp;gt;()&amp;gt;=0);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;  &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt; income = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Orders.Sum(o =&amp;gt; o.CalculatePrice());&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; income;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;In a “real world” application, should the evaluation of the total income be a mere sum, I’d have the O/RM generating a proper query. But, for the sake of the project, I only wanted both a mockable customer repository and the above shown method in order to set up a unit testing demo for the following service:&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt; CalculateSuggestedDiscountRate(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; customerId)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt;     Contract.Requires&amp;lt;ArgumentNullException&amp;gt;(customerId != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;, &lt;span style="color: #006080"&gt;"customerId"&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;     Contract.Requires&amp;lt;ArgumentException&amp;gt;(!&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrWhiteSpace(customerId), &lt;span style="color: #006080"&gt;"customerId"&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt;  &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt;     Customer customer = customerRepository.FindById(customerId);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt; income = customer.CalculateTotalIncome();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt; discount = 0;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt;   9:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (income &amp;gt; 5000)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt;  10:&lt;/span&gt;     {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt;  11:&lt;/span&gt;         &lt;span style="color: #008000"&gt;//Suggests a 6% discount if income&amp;gt;5000USD&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt;  12:&lt;/span&gt;         discount = 0.06M;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt;  13:&lt;/span&gt;     }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt;  14:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt;  15:&lt;/span&gt;     {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum16"&gt;  16:&lt;/span&gt;         &lt;span style="color: #008000"&gt;//Suggests a 1% discount for every 1000USD of income&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum17"&gt;  17:&lt;/span&gt;         discount = income / 100000;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum18"&gt;  18:&lt;/span&gt;     }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum19"&gt;  19:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; discount;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum20"&gt;  20:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;This way, I could write down the following test:&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; [TestMethod]&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Test_Calculation_Of_Suggested_Discount_Rate_For_Customers_With_Total_Income_Of_Less_Than_5000_Dollars()&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt; generatedIncome = 3500;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; customerId = &lt;span style="color: #006080"&gt;"FAKE1"&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt;     var custMockBuilder = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Mock&amp;lt;Customer&amp;gt;();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt;     custMockBuilder.Setup(c =&amp;gt; c.CalculateTotalIncome()).Returns(generatedIncome);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt;     var repoMockBuilder = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Mock&amp;lt;ICustomerRepository&amp;gt;();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt;   9:&lt;/span&gt;     repoMockBuilder.Setup(r =&amp;gt; r.FindById(customerId)).Returns(custMockBuilder.Object);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt;  10:&lt;/span&gt;  &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt;  11:&lt;/span&gt;     MarketingServices svc = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MarketingServices(repoMockBuilder.Object);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt;  12:&lt;/span&gt;     Assert.AreEqual&amp;lt;&lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;&amp;gt;(0.035M, svc.CalculateSuggestedDiscountRate(customerId));&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt;  13:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;To cut a long story short: the reader should look neither at the &lt;strong&gt;CalculateTotalIncome&lt;/strong&gt; nor at the &lt;strong&gt;CalculateSuggestedDiscountRate&lt;/strong&gt; service &lt;em&gt;per se&lt;/em&gt;, but at the unit test. Think about it as a &lt;strong&gt;MSTest&lt;/strong&gt; + &lt;strong&gt;Moq&lt;/strong&gt; demo, and maybe you’ll get the picture I wanted to give to the reader. Being the code targeted at someone who has attended a class/talk or read the book, I thought there was no way to have someone misunderstanding the scope of the project.&lt;/p&gt;

&lt;p&gt;The same goes for the domain model at large: if you take a look at it, you’ll notice that aggregates encapsulation is pretty low; I just managed to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;define an aggregate root abstraction (the &lt;strong&gt;IAggregateRoot&lt;/strong&gt; interface), and built an eco-system aware of it (i.e. the repositories which uses IAggregateRoot explicit implementation and code contracts to enforce domain logic) &lt;/li&gt;

  &lt;li&gt;have the aggregate roots implement factories in order to prevent bad instantiation to happen (builder pattern anyone?) &lt;/li&gt;

  &lt;li&gt;encapsulate some navigation properties having the domain model “users” forced to use domain logic (i.e. the, &lt;strong&gt;AddProduct&lt;/strong&gt; method of the &lt;strong&gt;Order&lt;/strong&gt; entity which is the only way to add a product to the order… or avoiding that, from a domain logic perspective) &lt;/li&gt;

  &lt;li&gt;added a bunch of domain services (i.e.: &lt;strong&gt;GetRelatedProducts&lt;/strong&gt;, &lt;strong&gt;CalculateSuggestedDiscountRate&lt;/strong&gt;, …) in order to show the differences lying in implementing domain logic within the model and/or by means of services &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Again, that was enough for my own needings; demo after demo, technology after technology (code contracts, entity framework POCO mapping, jquery, MVVM) NSK grew up and nearly became the “one size fits all” demo I needed in my talks. Up to late 2010/early 2011, I only managed to update NSK in order to remain useful for my own needings. &lt;/p&gt;

&lt;p&gt;All of a sudden, though, “developing” NSK wasn’t fun anymore so I settled down and asked myself what I wanted to do with it; my answer was: “make it a real application under the form of an Amazon-like e-commerce web site”. That would have justified the complexity DDD kicks in and also (hopefully) make the project a foundation for solutions we build at &lt;a href="http://www.manageddesigns.it/"&gt;Managed Designs&lt;/a&gt;. I opted to go for the CQRS way and started focusing of the front-end: so I quickly implemented a read model and started implementing a couple of user stories only to define a structure for the project (architecture, file system, NuGet-based pre build actions, …), only to discover that such a project is too much of an effort for a single person which is going to develop it in his spare time, so I contacted &lt;a href="http://nsk.codeplex.com/team/view"&gt;a bunch of friends&lt;/a&gt; in order to ask for their support. Then we stopped committing code and &lt;a href="http://goo.gl/cKtk7"&gt;started writing down the user stories&lt;/a&gt; that will lead our effort from now on.&lt;/p&gt;

&lt;p&gt;That’s why the read model and the domain model appear so similar, being the former a mere database reverse engineering and the latter the model that fitted my own “demoing” needings, but we’ll remove this model (and other code, such as the repositories) as soon as we’ll have the new ones, which will emerge from the user stories. Remember that I *still* need demoes for my talks, so I won’t be able to remove “demoable” code until when I have a replacement for it. The nice part is that we &lt;u&gt;think&lt;/u&gt; that the new model will be composed by “real” aggregates and that we’ll switch from SQL server to a NoSQL database, so the “R” and “C” parts are going to be pretty different.&lt;/p&gt;

&lt;p&gt;At this very moment, being the “code writing” on a hiatus, the only code I would recommend a casual downloader to look at is the stack that shows the recommended projects onto the home page, which picks the products following the following strategy: “&lt;em&gt;Given all products-&amp;gt;Choose the ones we are selling (which, of course, aren’t all the products we have in the db)-&amp;gt;Then select only the available ones-&amp;gt;Let’s pick up the projection we need within this view&lt;/em&gt;”. That happens picking them (the products) by means of an expression tree that is composed while goin’ up the application stack: that’s an idiom we at &lt;a href="http://www.manageddesigns.it/"&gt;Managed Designs&lt;/a&gt; nicknamed &lt;strong&gt;LET&lt;/strong&gt; (which stands for &lt;em&gt;Layered Expression Trees&lt;/em&gt;) and we think that it’s a pretty powerful idiomatic way to express logic in a DDD context. I’ll talk about it at the &lt;a href="http://ugialt.net/"&gt;next local ALT.net event&lt;/a&gt;, and dedicate soon a blog post to it.&lt;/p&gt;

&lt;p&gt;To sum it up: if you’re looking for a sample application, you’d better search for a project sporting a release version (which is &lt;a href="http://nsk.codeplex.com/releases"&gt;something NSK still doesn’t&lt;/a&gt;) or, at least, wait for we to implement some more user stories in order to allow the whole design to consolidate. In the meantime, the project can still be looked at in order to take advantage of some “pills” you could be interested in for your projects, such as:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;JQueryUI&lt;/strong&gt; integration with ASP.NET MVC (i.e.: the DateTime partial view implemented for both &lt;strong&gt;WebFormsEngine&lt;/strong&gt; and &lt;strong&gt;Razor&lt;/strong&gt; engine) &lt;/li&gt;

  &lt;li&gt;MVC and WCF custom factories &lt;/li&gt;

  &lt;li&gt;NuGet-based pre build actions in order to easen you first “compile&amp;amp;run” (for those using the recently released v1.6 of NuGet, I’d recommend to have a look at the “package restore” feature) &lt;/li&gt;

  &lt;li&gt;Code Contracts aware IRepository interface (don’t focus on actual designs: the real meat lies in having IAggregateRoot + code contracts enforcing your validation even when application code “forgets” to do domain object validation) &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;Rss&lt;/strong&gt; and &lt;strong&gt;Atom&lt;/strong&gt; custom &lt;strong&gt;ActionResult&lt;/strong&gt;s for ASP.NET MVC, taking advantage of framework’s built-in serializers &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s all code you can use (and refactor to satisfy your own needings) due to the license chosen. Enjoy NSK!&lt;/p&gt;

&lt;p&gt;P.S.: I know, project’s description on Codeplex sucks bad. Mea culpa: I’ll fix it ASAP.&lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org/mrbrightside/aggbug/100688.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Andrea Saltarello</dc:creator>
            <guid>http://blogs.ugidotnet.org/mrbrightside/archive/2012/01/10/no-nsk-is-not-about-northwind.aspx</guid>
            <pubDate>Tue, 10 Jan 2012 13:17:30 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/mrbrightside/archive/2012/01/10/no-nsk-is-not-about-northwind.aspx#feedback</comments>
            <slash:comments>56</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/mrbrightside/comments/commentRss/100688.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/mrbrightside/services/trackbacks/100688.aspx</trackback:ping>
        </item>
        <item>
            <title>NHDay debriefed</title>
            <link>http://blogs.ugidotnet.org/mrbrightside/archive/2010/10/13/nhday.aspx</link>
            <description>&lt;p&gt;“Astonishing”: that’s the only way I have to describe how much I enjoyed living the &lt;strong&gt;&lt;a href="http://nhday.eu/"&gt;NHDay&lt;/a&gt;&lt;/strong&gt;: I sincerely thank the staff, the speakers and all attendants for having made possibile such an event. As a “side note”, here are the &lt;a href="http://goo.gl/rJF6"&gt;slides&lt;/a&gt; &amp;amp; &lt;a href="http://downloads.ugidotnet.org/blog/pape/NHDay_demo.zip"&gt;demos&lt;/a&gt; I’ve shown. Ad maiora!&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:aad69712-3ee5-4dc2-84c3-187560288f08" class="wlWriterEditableSmartContent"&gt;Technorati Tag: &lt;a href="http://technorati.com/tags/nhday" rel="tag"&gt;nhday&lt;/a&gt;,&lt;a href="http://technorati.com/tags/ORM" rel="tag"&gt;ORM&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.ugidotnet.org/mrbrightside/aggbug/99349.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Andrea Saltarello</dc:creator>
            <guid>http://blogs.ugidotnet.org/mrbrightside/archive/2010/10/13/nhday.aspx</guid>
            <pubDate>Wed, 13 Oct 2010 16:09:42 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/mrbrightside/archive/2010/10/13/nhday.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/mrbrightside/comments/commentRss/99349.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/mrbrightside/services/trackbacks/99349.aspx</trackback:ping>
        </item>
        <item>
            <title>NHDay, as one of the other speakers</title>
            <link>http://blogs.ugidotnet.org/mrbrightside/archive/2010/10/06/nhday-as-one-of-the-other-speakers.aspx</link>
            <description>&lt;p&gt;In real life, you are not allowed to drive a car without a licence: that’s both for your own and other’s safety. In our dev life, we can start using O/RMs without knowing what an identity map or an object space is, which leads to low-perf, memory hungry applications and, in the end, to ourselves blaming O/RMs for them.&lt;/p&gt;  &lt;p&gt;If the Five Ws of O/RMs matter to you, then we could meet &lt;a href="http://nhday.eu/en/call-for-presenters.aspx#p3"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:2497c1da-1660-42f2-98da-16b3f8594eae" class="wlWriterEditableSmartContent"&gt;Technorati Tag: &lt;a href="http://technorati.com/tags/NHDay" rel="tag"&gt;NHDay&lt;/a&gt;,&lt;a href="http://technorati.com/tags/ORM" rel="tag"&gt;ORM&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.ugidotnet.org/mrbrightside/aggbug/99322.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Andrea Saltarello</dc:creator>
            <guid>http://blogs.ugidotnet.org/mrbrightside/archive/2010/10/06/nhday-as-one-of-the-other-speakers.aspx</guid>
            <pubDate>Wed, 06 Oct 2010 10:12:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/mrbrightside/archive/2010/10/06/nhday-as-one-of-the-other-speakers.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/mrbrightside/comments/commentRss/99322.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/mrbrightside/services/trackbacks/99322.aspx</trackback:ping>
        </item>
        <item>
            <title>NSK goes to CodePlex</title>
            <link>http://blogs.ugidotnet.org/mrbrightside/archive/2006/09/24/48592.aspx</link>
            <description>&lt;p&gt;&lt;strong&gt;&lt;a href="http://download.manageddesigns.it/nsk.aspx" target="_blank"&gt;Northwind Starter Kit&lt;/a&gt;&lt;/strong&gt; has moved to &lt;strong&gt;CodePlex&lt;/strong&gt;: the new home page is &lt;a href="http://www.codeplex.com/Wiki/View.aspx?ProjectName=NSK" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Technorati Tags: &lt;a href="http://technorati.com/tag/codeplex" rel="tag"&gt;codeplex&lt;/a&gt; &lt;a href="http://technorati.com/tag/NSK" rel="tag"&gt;NSK&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org/mrbrightside/aggbug/48592.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Andrea Saltarello</dc:creator>
            <guid>http://blogs.ugidotnet.org/mrbrightside/archive/2006/09/24/48592.aspx</guid>
            <pubDate>Sun, 24 Sep 2006 13:03:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/mrbrightside/archive/2006/09/24/48592.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/mrbrightside/comments/commentRss/48592.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/mrbrightside/services/trackbacks/48592.aspx</trackback:ping>
        </item>
        <item>
            <title>INETA web site talks about italian UG meetings</title>
            <category>INETA</category>
            <link>http://blogs.ugidotnet.org/mrbrightside/archive/2006/07/14/44646.aspx</link>
            <description>&lt;p&gt;Thanks to my friend &lt;a href="http://weblogs.asp.net/lbarbieri/"&gt;Lorenzo&lt;/a&gt;, the italian &lt;a href="http://europe.ineta.org/Countries/Italy/Home/tabid/231/Default.aspx"&gt;page&lt;/a&gt; of INETA Europe website is up and running. Even better, the page shows the annoucement of UGIdotNET's next meeting. All hail for Lorenzo!&lt;/p&gt; &lt;p&gt;Technorati Tags: &lt;a href="http://technorati.com/tag/UGIdotNET" rel="tag"&gt;UGIdotNET&lt;/a&gt; &lt;a href="http://technorati.com/tag/INETA" rel="tag"&gt;INETA&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org/mrbrightside/aggbug/44646.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Andrea Saltarello</dc:creator>
            <guid>http://blogs.ugidotnet.org/mrbrightside/archive/2006/07/14/44646.aspx</guid>
            <pubDate>Fri, 14 Jul 2006 13:58:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/mrbrightside/archive/2006/07/14/44646.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/mrbrightside/comments/commentRss/44646.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/mrbrightside/services/trackbacks/44646.aspx</trackback:ping>
        </item>
        <item>
            <title>Northwind Starter Kit source code released</title>
            <link>http://blogs.ugidotnet.org/mrbrightside/archive/2006/03/01/35838.aspx</link>
            <description>&lt;p&gt;As my friend Dino &lt;a href="http://weblogs.asp.net/despos/archive/2006/02/28/439257.aspx"&gt;already announced&lt;/a&gt;, the &lt;a href="http://nsk.sourceforge.net/"&gt;&lt;strong&gt;Northwind Starter Kit&lt;/strong&gt;&lt;/a&gt; has finally been released. Let me just bore you with a little bit of history. During the last years, I noticed a growing interest within the .NET community for topics (I'm in love with) like: design patterns, unit testing, (agile) methodologies and so on. Being a regular speaker at Microsoft events here in Italy, I found myself in need to set up presentations and demos covering these topics. Instead of creating "synthetic" code, I decided to create a simple "reference" application in order to show it during my talks. This app:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Should be based on a layered architecture, implemented as a service layer and sporting a "real world" domain model  &lt;/li&gt;&lt;li&gt;Should use well-known design patterns and eventually idiomatic design considerations, showing the rationale behind all these choices  &lt;/li&gt;&lt;li&gt;Should use Northwind as its default database, in order to easen its deploy. It should also be decoupled from the physical structure of the database, in order to allow to use different stores  &lt;/li&gt;&lt;li&gt;Should offer unit tests  &lt;/li&gt;&lt;li&gt;Should be available with both web-based and smart client GUIs  &lt;/li&gt;&lt;li&gt;Should be documented in... some way :-)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Since I'm not a full time speaker/trainer/author (I must confess that in my real life I work as a software architect at &lt;a href="http://www.manageddesigns.it/"&gt;Managed Designs&lt;/a&gt;), I could only use spare time in order to implement the the application: I had some working code, but it was far from being (and still is, to be honest) the "reference app" I dreamt about. So I looked around in order to make this app a community supported project, christening it "Northwind Starter Kit" (NSK) and releasing it under the &lt;a href="http://www.opensource.org/licenses/cpl1.0.php"&gt;Common Public License&lt;/a&gt;. Then I contacted &lt;a href="http://blogs.ugidotnet.org/luKa/"&gt;luKa&lt;/a&gt; and &lt;a href="http://blogs.aspitalia.com/rickyvr/"&gt;Ricky&lt;/a&gt; that accepted to be part of the "core team" of the project, and later even Dino joined the project. Last week we released a first drop of the code, on which we're still working. So, what re we going to do from now on? We won't save the world. We'll simply continue to work on the project, hoping to see both the app and the team growing as time passes. There's still a *lot* of work to do. Would you like to help us? &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=153012"&gt;Download&lt;/a&gt; the archive, expand it, modify the connection string stored within the config file, and run your favourite flavour of the GUI (windows or web). Should you: have trouble doing this, experience exceptions using the application or spot errors within the source code, please &lt;a href="http://blogs.ugidotnet.org/mrbrightside/contact.aspx"&gt;contact me&lt;/a&gt; or discuss the issue(s) using the &lt;a href="http://sourceforge.net/forum/?group_id=153012"&gt;forums&lt;/a&gt; in order to give us feedback. We hope we will be able to set up a collaborative development process: time will tell, but in the meanwhile, we'll continue to work onto NSK.&lt;/p&gt; &lt;p&gt;Technorati Tags: &lt;a href="http://technorati.com/tag/NSK" rel="tag"&gt;NSK&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org/mrbrightside/aggbug/35838.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Andrea Saltarello</dc:creator>
            <guid>http://blogs.ugidotnet.org/mrbrightside/archive/2006/03/01/35838.aspx</guid>
            <pubDate>Wed, 01 Mar 2006 03:32:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/mrbrightside/archive/2006/03/01/35838.aspx#feedback</comments>
            <slash:comments>27</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/mrbrightside/comments/commentRss/35838.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/mrbrightside/services/trackbacks/35838.aspx</trackback:ping>
        </item>
        <item>
            <title>New kids on the... blog</title>
            <link>http://blogs.ugidotnet.org/mrbrightside/archive/2006/02/16/34945.aspx</link>
            <description>It seems that my friend (and VB/WPF guru at &lt;A href="http://www.manageddesigns.it"&gt;Managed Designs&lt;/A&gt;) Corrado started its english &lt;A href="http://blogs.ugidotnet.org/ccavalli"&gt;blog&lt;/A&gt;. Don't miss it!&lt;img src="http://blogs.ugidotnet.org/mrbrightside/aggbug/34945.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Andrea Saltarello</dc:creator>
            <guid>http://blogs.ugidotnet.org/mrbrightside/archive/2006/02/16/34945.aspx</guid>
            <pubDate>Thu, 16 Feb 2006 01:20:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/mrbrightside/archive/2006/02/16/34945.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/mrbrightside/comments/commentRss/34945.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/mrbrightside/services/trackbacks/34945.aspx</trackback:ping>
        </item>
        <item>
            <title>[OT] Anders Powers</title>
            <link>http://blogs.ugidotnet.org/mrbrightside/archive/2005/11/03/29159.aspx</link>
            <description>Ok... Coulnd't resist to reveal &lt;A href="http://www.wiltamuth.com/blog/shipparty/"&gt;Anders real identity&lt;/A&gt; to the world: the truth is out there!&amp;nbsp;&amp;lt;g&amp;gt;&lt;img src="http://blogs.ugidotnet.org/mrbrightside/aggbug/29159.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Andrea Saltarello</dc:creator>
            <guid>http://blogs.ugidotnet.org/mrbrightside/archive/2005/11/03/29159.aspx</guid>
            <pubDate>Thu, 03 Nov 2005 20:24:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/mrbrightside/archive/2005/11/03/29159.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/mrbrightside/comments/commentRss/29159.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/mrbrightside/services/trackbacks/29159.aspx</trackback:ping>
        </item>
        <item>
            <title>Membership API article (reloaded)</title>
            <link>http://blogs.ugidotnet.org/mrbrightside/archive/2005/10/29/28930.aspx</link>
            <description>&lt;A href="http://weblogs.asp.net/despos" target=_blank&gt;Dino&lt;/A&gt; just told me that our &lt;A href="http://msdn.microsoft.com/msdnmag/issues/05/11/Membership/default.aspx"&gt;article&lt;/A&gt; has been puslished&amp;nbsp;in the european edition&amp;nbsp;of MSDN Magazine, too.&amp;nbsp;Honest: I'm waiting&amp;nbsp;to receive my copy in order to understan how&amp;nbsp;this new&amp;nbsp;edition&amp;nbsp;of the mag differentiates from the US one.&lt;img src="http://blogs.ugidotnet.org/mrbrightside/aggbug/28930.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Andrea Saltarello</dc:creator>
            <guid>http://blogs.ugidotnet.org/mrbrightside/archive/2005/10/29/28930.aspx</guid>
            <pubDate>Sat, 29 Oct 2005 17:25:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/mrbrightside/archive/2005/10/29/28930.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/mrbrightside/comments/commentRss/28930.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/mrbrightside/services/trackbacks/28930.aspx</trackback:ping>
        </item>
        <item>
            <title>Some thoughts about ASP.NET 2.0</title>
            <link>http://blogs.ugidotnet.org/mrbrightside/archive/2005/10/29/28921.aspx</link>
            <description>&lt;P&gt;As Soma &lt;A href="http://blogs.msdn.com/somasegar/archive/2005/10/27/485665.aspx" target=_blank&gt;pointed out&lt;/A&gt;, VS2005 is finally out: it's been a long way since the early bits we (alpha testers) got in May 2003.&amp;nbsp;&lt;A href="http://www.microsoft.com/emea/msdn/betaexperience/nlarchive/issue_4/saltarello.aspx" target=_blank&gt;These&lt;/A&gt; are a bunch of thoughts of mine about ASP.NET v2 I wrote for Microsoft EMEA "Beta Experience" newsletter.&lt;/P&gt;&lt;img src="http://blogs.ugidotnet.org/mrbrightside/aggbug/28921.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Andrea Saltarello</dc:creator>
            <guid>http://blogs.ugidotnet.org/mrbrightside/archive/2005/10/29/28921.aspx</guid>
            <pubDate>Sat, 29 Oct 2005 14:01:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/mrbrightside/archive/2005/10/29/28921.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/mrbrightside/comments/commentRss/28921.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/mrbrightside/services/trackbacks/28921.aspx</trackback:ping>
        </item>
    </channel>
</rss>