<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>There and Back Again : Domain Driven Design</title><link>http://blogs.msdn.com/howard_dierking/archive/tags/Domain+Driven+Design/default.aspx</link><description>Tags: Domain Driven Design</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Managing Data Streams With C# Iterators</title><link>http://blogs.msdn.com/howard_dierking/archive/2008/07/01/managing-data-streams-with-c-iterators.aspx</link><pubDate>Wed, 02 Jul 2008 09:33:43 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8680327</guid><dc:creator>hdierking</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/howard_dierking/comments/8680327.aspx</comments><wfw:commentRss>http://blogs.msdn.com/howard_dierking/commentrss.aspx?PostID=8680327</wfw:commentRss><description>&lt;p&gt;Architecturally, I lean pretty heavily towards 2 philosophies - &lt;a href="http://www.domaindrivendesign.org/"&gt;Domain Driven Design&lt;/a&gt; and the &lt;a href="http://martinfowler.com/books.html#eaa"&gt;Rich Domain Model&lt;/a&gt; pattern.&amp;#160; And while neither requires the other for success (contrary to much of what you read out there), they seem to work well together for me, and hence, I have internalized them into a single approach for building solutions.&lt;/p&gt;  &lt;p&gt;As a result of my approach, I typically start with (and end up with) an assembly for my domain model (another assembly for my domain model's automated unit tests), an assembly for my presentation logic, and an assembly for my data access layer - or where to put it into DDD terms, the layer where my repository objects live.&amp;#160; There is an ongoing debate about how the assembly references should look - I'm not going to get into the nuances of the arguments, but these seem to be the 2 basic philosophies:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Have the data access assembly reference the domain model assembly with the UI layer referencing both (and calling the repository objects directly to get domain instances) &lt;/li&gt;    &lt;li&gt;Have the UI layer reference only the domain model assembly reference and have the domain model objects call their respective repository objects in the data access layer &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;There are a couple other more specific approaches, but I think that those give you an idea of the underlying philosophies.&amp;#160; I tend to gravitate towards philosophy #1, though I'm much more comfortable with #2 when done in conjunction with a DI container like &lt;a href="http://www.castleproject.org/"&gt;Windsor&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;So there you have my general layering philosophy - UI talks to repository to get and work on domain objects.&amp;#160; Why is this important?&amp;#160; Because one of the cases that has always made me a little uncomfortable is the classic case where I need to generate a UI element like a grid and I don't need to bring back the entire domain object (or in DDD terms, the entire aggregate).&amp;#160; The 3 major approaches I have seen and used are:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Return a IDbDataReader instance from the appropriate repository object in the data access layer &lt;/li&gt;    &lt;li&gt;Fetch all of the relevant results into an in-memory data structure in the data access layer and hand that back to the caller &lt;/li&gt;    &lt;li&gt;Use a SqlDataSource object at the UI layer and configure it with all of the proper query information &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;I don't really like any of these solutions.&amp;#160; The problem with solution #1 is that once you pass the stream reader out of the scope where it was initiated, you are relying on the consumer code to close the reader.&amp;#160; The problem with solution #2 is that you're potentially buffering a lot of data that is going to be almost immediately discarded.&amp;#160; The problem with solution #3 (which is the one I have ended up using most frequently) is that it puts you in a situation where you are managing data access in multiple places.&lt;/p&gt;  &lt;p&gt;So I was thinking the other night that the ideal solution would be one where I could, in the same scope, manage the lifetime of my stream reader object, but still hand back some kind of safe reference to that stream to calling code - and then I remembered that &lt;a href="http://msdn.microsoft.com/en-us/magazine/cc163682.aspx"&gt;really cool C# iterators feature&lt;/a&gt; that I had thought was nifty but very rarely used.&amp;#160; I added the following method to my repository class (DB is standard AdventureWorks - ignore the horrible practice of not parameterizing my query).&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ProductsRepository
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;private const string &lt;/span&gt;COMMAND_TEXT =
        &lt;span style="color: #a31515"&gt;&amp;quot;select top {0} ProductID, [Name] from Production.vProductAndDescription where CultureID = 'en'&amp;quot;&lt;/span&gt;;

    &lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt; GetProducts(&lt;span style="color: blue"&gt;int &lt;/span&gt;numberRecords) {
        &lt;span style="color: green"&gt;/*
         * in this example, numberRecords is a very simple illustration 
         * of how you could expose more complex criteria parameters based
         * on the specific domain
         */
        &lt;/span&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;conn = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SqlConnection&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Settings&lt;/span&gt;.Default.AdWksCN))
        &lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;cmd = conn.CreateCommand()) {
            cmd.CommandText = &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(COMMAND_TEXT, numberRecords);
            conn.Open();
            &lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;rdr = cmd.ExecuteReader()) {
                &lt;span style="color: blue"&gt;if &lt;/span&gt;(rdr != &lt;span style="color: blue"&gt;null&lt;/span&gt;) {
                    &lt;span style="color: blue"&gt;while &lt;/span&gt;(rdr.Read()) {
                        &lt;span style="color: blue"&gt;var &lt;/span&gt;productID = rdr.GetInt32(0);
                        &lt;span style="color: blue"&gt;var &lt;/span&gt;name = rdr.GetString(1);
                        &lt;strong&gt;&lt;span style="color: blue"&gt;yield return new &lt;/span&gt;{productID, name};&lt;/strong&gt;
                    }
                }
            }
        }
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Note the yield return statement - when the compiler sees this, it generates a whole other class that implements IEnumerable&amp;lt;object&amp;gt; and contains the code in your method along with a whole bunch of other code to manage the enumeration activity.&amp;#160; For example, here's the code for the MoveNext method of my generated enumerable class (ala Reflector).&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;private bool &lt;/span&gt;MoveNext()
{
    &lt;span style="color: blue"&gt;bool &lt;/span&gt;CS$1$0000;
    &lt;span style="color: blue"&gt;try
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;int &lt;/span&gt;CS$4$0001 = &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;1__state;
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(CS$4$0001 != 0)
        {
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(CS$4$0001 != 4)
            {
                &lt;span style="color: blue"&gt;goto &lt;/span&gt;Label_0127;
            }
            &lt;span style="color: blue"&gt;goto &lt;/span&gt;Label_00F7;
        }
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;1__state = -1;
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;conn&amp;gt;5__1 = &lt;span style="color: blue"&gt;new &lt;/span&gt;SqlConnection(Settings.Default.AdWksCN);
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;1__state = 1;
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;cmd&amp;gt;5__2 = &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;conn&amp;gt;5__1.CreateCommand();
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;1__state = 2;
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;cmd&amp;gt;5__2.CommandText = &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(
            &lt;span style="color: #a31515"&gt;&amp;quot;select top {0} ProductID, [Name] from Production.vProductAndDescription &amp;quot; &lt;/span&gt;+ 
            &lt;span style="color: #a31515"&gt;&amp;quot;where CultureID = 'en'&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;this&lt;/span&gt;.numberRecords);
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;conn&amp;gt;5__1.Open();
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;rdr&amp;gt;5__3 = &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;cmd&amp;gt;5__2.ExecuteReader();
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;1__state = 3;
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;rdr&amp;gt;5__3 != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
        {
            &lt;span style="color: blue"&gt;while &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;rdr&amp;gt;5__3.Read())
            {
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;productID&amp;gt;5__4 = &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;rdr&amp;gt;5__3.GetInt32(0);
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;name&amp;gt;5__5 = &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;rdr&amp;gt;5__3.GetString(1);
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;2__current = &lt;span style="color: blue"&gt;new &lt;/span&gt;{ productID = &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;productID&amp;gt;5__4, name = &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;name&amp;gt;5__5 };
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;1__state = 4;
                &lt;span style="color: blue"&gt;return true&lt;/span&gt;;
            Label_00F7:
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;1__state = 3;
            }
        }
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;m__Finally8();
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;m__Finally7();
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;m__Finally6();
    Label_0127:
        CS$1$0000 = &lt;span style="color: blue"&gt;false&lt;/span&gt;;
    }
    fault
    {
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.System.IDisposable.Dispose();
    }
    &lt;span style="color: blue"&gt;return &lt;/span&gt;CS$1$0000;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;If you don't go cross-eyed from reading the compiler's choice of variable names, what you can see here is that the generated enumerator runs the query the first time MoveNext is called, then for subsequent calls, it simply calls the Read method on the data reader and returns the data elements extracted from the row.&amp;#160; When it is done enumerating, it cleans itself up, which includes calling the rest of the cleanup code you defined in the body of your method.&lt;/p&gt;

&lt;p&gt;So what's nice about this approach?&amp;#160; Well, first and foremost, I can keep all of my data access code, including projection style queries with potentially complex criteria, in the same place as my object persistence data access code.&amp;#160; At the same time, since I'm returning IEnumerable, I still retain all the benefits of a simple usage pattern (including data binding).&amp;#160; For me, this is a nice hybrid solution for many of those cases where you just need to get a little off the rails!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8680327" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Microsoft+.NET+Programming/default.aspx">Microsoft .NET Programming</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Domain+Driven+Design/default.aspx">Domain Driven Design</category></item></channel></rss>