﻿<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Ayende @ Rahien</title><link>http://ayende.com/blog/</link><description>Ayende @ Rahien</description><copyright>Copyright (C) Ayende Rahien  2004 - 2012 (c) 2013</copyright><ttl>60</ttl><item><title>Public Service Announcement: Git master repositories for the Rhino Tools projects</title><description>&lt;p&gt;There have been some changes, and it seems that it is hard to track them. Here are where you can find the master repositories for the rhino tools projects:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Rhino Commons - &lt;a href="https://github.com/lorenzomelato/rhino-commons"&gt;https://github.com/lorenzomelato/rhino-commons&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Rhino Service Bus- &lt;a title="https://github.com/hibernating-rhinos/rhino-esb" href="https://github.com/hibernating-rhinos/rhino-esb"&gt;https://github.com/hibernating-rhinos/rhino-esb&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Rhino Licensing - &lt;a title="https://github.com/hibernating-rhinos/rhino-licensing" href="https://github.com/hibernating-rhinos/rhino-licensing"&gt;https://github.com/hibernating-rhinos/rhino-licensing&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Rhino ETL - &lt;a title="https://github.com/hibernating-rhinos/rhino-etl" href="https://github.com/hibernating-rhinos/rhino-etl"&gt;https://github.com/hibernating-rhinos/rhino-etl&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Rhino Security - &lt;a title="https://github.com/hibernating-rhinos/rhino-security" href="https://github.com/hibernating-rhinos/rhino-security"&gt;https://github.com/hibernating-rhinos/rhino-security&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Rhino Persistent Hash Table - &lt;a title="https://github.com/hibernating-rhinos/rhino-pht" href="https://github.com/hibernating-rhinos/rhino-pht"&gt;https://github.com/hibernating-rhinos/rhino-pht&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Rhino Distributed Hash Table - &lt;a title="https://github.com/hibernating-rhinos/rhino-dht" href="https://github.com/hibernating-rhinos/rhino-dht"&gt;https://github.com/hibernating-rhinos/rhino-dht&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Rhino DSL - &lt;a title="https://github.com/hibernating-rhinos/rhino-dsl" href="https://github.com/hibernating-rhinos/rhino-dsl"&gt;https://github.com/hibernating-rhinos/rhino-dsl&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Rhino Mocks - &lt;a title="https://github.com/hibernating-rhinos/rhino-mocks" href="https://github.com/hibernating-rhinos/rhino-mocks"&gt;https://github.com/hibernating-rhinos/rhino-mocks&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Rhino Queues - &lt;a title="https://github.com/hibernating-rhinos/rhino-queues" href="https://github.com/hibernating-rhinos/rhino-queues"&gt;https://github.com/hibernating-rhinos/rhino-queues&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;</description><link>http://ayende.com/blog/4735/public-service-announcement-git-master-repositories-for-the-rhino-tools-projects?key=3e567a32-9e98-4920-835d-c3ce48a64596</link><guid>http://ayende.com/blog/4735/public-service-announcement-git-master-repositories-for-the-rhino-tools-projects?key=3e567a32-9e98-4920-835d-c3ce48a64596</guid><pubDate>Tue, 28 Dec 2010 08:07:59 GMT</pubDate></item><item><title>On PSake</title><description>&lt;p&gt;&lt;a href="http://codebetter.com/blogs/james.kovacs/archive/2008/06/27/introducing-psake.aspx"&gt;James Kovacks&lt;/a&gt; introduced &lt;a href="http://code.google.com/p/psake/"&gt;psake&lt;/a&gt; ( a power shell based build system )over a year ago, and at the time, I gave it a glance and decided that it was interesting, but not worth further investigation.&lt;/p&gt;  &lt;p&gt;This weekend, as I was restructuring my Rhino Tools project, I realized that I need to touch the build system as well. The Rhino Tools build system has been through several projects, and was originally ported from Hibernate. It is NAnt based, complex, and can do just about everything that you want expect be easily understandable.&lt;/p&gt;  &lt;p&gt;It became clear to me very quickly that it ain’t going to be easy to change the way it works, nor would it be easy to modify that to reflect the new structure. There are other issues with complex build systems, they tend to create zones of “there be dragons”, where only the initiated go, and even they go with trepidation. I decided to take advantage of the changes that I am already making to get a simpler build system.&lt;/p&gt;  &lt;p&gt;I had a couple of options open to me: Rake and Bake.&lt;/p&gt;  &lt;p&gt;Bake seemed natural, until I remember that no one touched it in a year or two. Beside, I can only stretch NIH so far :-). And while I know that people rave about rake, I did &lt;em&gt;not&lt;/em&gt; want to introduce a Ruby dependency on my build system. I know that it was an annoyance when I had to build Fluent NHibernate.&lt;/p&gt;  &lt;p&gt;One thing that I knew that I am not willing to go back to was editing XML, so I started looking at other build systems, ending up running into PSake.&lt;/p&gt;  &lt;p&gt;There are a few interesting things that reading about it brought to mind. First, NAnt doesn’t cut it anymore. It can’t build WPF applications nor handle multi targeting well. Second, I am already managing the compilation part of the build using MSBuild, thanks to Visual Studio.&lt;/p&gt;  &lt;p&gt;That leave the build system with executing msbuild, setting up directories, executing tests, running post build tools, etc.&lt;/p&gt;  &lt;p&gt;PSake handles those well, since the execution environment is the command line. The syntax is nice, just enough to specify tasks and dependencies, but everything else is just pure command line. The following is Rhino Mocks build script, using PSake:&lt;/p&gt;  &lt;blockquote&gt;   &lt;div&gt;     &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;properties { 
  $base_dir  = resolve-path .
  $lib_dir = &lt;span style="color: #006080"&gt;"$base_dir\SharedLibs"&lt;/span&gt;
  $build_dir = &lt;span style="color: #006080"&gt;"$base_dir\build"&lt;/span&gt; 
  $buildartifacts_dir = &lt;span style="color: #006080"&gt;"$build_dir\" 
  $sln_file = "&lt;/span&gt;$base_dir\Rhino.Mocks-vs2008.sln&lt;span style="color: #006080"&gt;" 
  $version = "&lt;/span&gt;3.6.0.0&lt;span style="color: #006080"&gt;"
  $tools_dir = "&lt;/span&gt;$base_dir\Tools&lt;span style="color: #006080"&gt;"
  $release_dir = "&lt;/span&gt;$base_dir\Release&lt;span style="color: #006080"&gt;"
} 

task default -depends Release

task Clean { 
  remove-item -force -recurse $buildartifacts_dir -ErrorAction SilentlyContinue 
  remove-item -force -recurse $release_dir -ErrorAction SilentlyContinue 
} 

task Init -depends Clean { 
    . .\psake_ext.ps1
    Generate-Assembly-Info `
        -file "&lt;/span&gt;$base_dir\Rhino.Mocks\Properties\AssemblyInfo.cs&lt;span style="color: #006080"&gt;" `
        -title "&lt;/span&gt;Rhino Mocks $version&lt;span style="color: #006080"&gt;" `
        -description "&lt;/span&gt;Mocking Framework &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; .NET&lt;span style="color: #006080"&gt;" `
        -company "&lt;/span&gt;Hibernating Rhinos&lt;span style="color: #006080"&gt;" `
        -product "&lt;/span&gt;Rhino Mocks $version&lt;span style="color: #006080"&gt;" `
        -version $version `
        -copyright "&lt;/span&gt;Hibernating Rhinos &amp;amp; Ayende Rahien 2004 - 2009&lt;span style="color: #006080"&gt;"
        
    Generate-Assembly-Info `
        -file "&lt;/span&gt;$base_dir\Rhino.Mocks.Tests\Properties\AssemblyInfo.cs&lt;span style="color: #006080"&gt;" `
        -title "&lt;/span&gt;Rhino Mocks Tests $version&lt;span style="color: #006080"&gt;" `
        -description "&lt;/span&gt;Mocking Framework &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; .NET&lt;span style="color: #006080"&gt;" `
        -company "&lt;/span&gt;Hibernating Rhinos&lt;span style="color: #006080"&gt;" `
        -product "&lt;/span&gt;Rhino Mocks Tests $version&lt;span style="color: #006080"&gt;" `
        -version $version `
        -clsCompliant "&lt;/span&gt;&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;&lt;span style="color: #006080"&gt;" `
        -copyright "&lt;/span&gt;Hibernating Rhinos &amp;amp; Ayende Rahien 2004 - 2009&lt;span style="color: #006080"&gt;"
        
    Generate-Assembly-Info `
        -file "&lt;/span&gt;$base_dir\Rhino.Mocks.Tests.Model\Properties\AssemblyInfo.cs&lt;span style="color: #006080"&gt;" `
        -title "&lt;/span&gt;Rhino Mocks Tests Model $version&lt;span style="color: #006080"&gt;" `
        -description "&lt;/span&gt;Mocking Framework &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; .NET&lt;span style="color: #006080"&gt;" `
        -company "&lt;/span&gt;Hibernating Rhinos&lt;span style="color: #006080"&gt;" `
        -product "&lt;/span&gt;Rhino Mocks Tests Model $version&lt;span style="color: #006080"&gt;" `
        -version $version `
        -clsCompliant "&lt;/span&gt;&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;&lt;span style="color: #006080"&gt;" `
        -copyright "&lt;/span&gt;Hibernating Rhinos &amp;amp; Ayende Rahien 2004 - 2009&lt;span style="color: #006080"&gt;"
        
    new-item $release_dir -itemType directory 
    new-item $buildartifacts_dir -itemType directory 
    cp $tools_dir\MbUnit\*.* $build_dir
} 

task Compile -depends Init { 
  exec msbuild "&lt;/span&gt;/p:OutDir=&lt;span style="color: #006080"&gt;""&lt;/span&gt;$buildartifacts_dir &lt;span style="color: #006080"&gt;""&lt;/span&gt; $sln_file&lt;span style="color: #006080"&gt;"
} 

task Test -depends Compile {
  $old = pwd
  cd $build_dir
  exec "&lt;/span&gt;.\MbUnit.Cons.exe&lt;span style="color: #006080"&gt;" "&lt;/span&gt;$build_dir\Rhino.Mocks.Tests.dll&lt;span style="color: #006080"&gt;"
  cd $old        
}

task Merge {
    $old = pwd
    cd $build_dir
    
    Remove-Item Rhino.Mocks.Partial.dll -ErrorAction SilentlyContinue 
    Rename-Item $build_dir\Rhino.Mocks.dll Rhino.Mocks.Partial.dll
    
    &amp;amp; $tools_dir\ILMerge.exe Rhino.Mocks.Partial.dll `
        Castle.DynamicProxy2.dll `
        Castle.Core.dll `
        /out:Rhino.Mocks.dll `
        /t:library `
        "&lt;/span&gt;/keyfile:$base_dir\ayende-open-source.snk&lt;span style="color: #006080"&gt;" `
        "&lt;/span&gt;/internalize:$base_dir\ilmerge.exclude&lt;span style="color: #006080"&gt;"
    if ($lastExitCode -ne 0) {
        throw "&lt;/span&gt;Error: Failed to merge assemblies!&lt;span style="color: #006080"&gt;"
    }
    cd $old
}

task Release -depends Test, Merge {
    &amp;amp; $tools_dir\zip.exe -9 -A -j `
        $release_dir\Rhino.Mocks.zip `
        $build_dir\Rhino.Mocks.dll `
        $build_dir\Rhino.Mocks.xml `
        license.txt `
        acknowledgements.txt
    if ($lastExitCode -ne 0) {
        throw "&lt;/span&gt;Error: Failed to execute ZIP command"
    }
}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is about 50 lines, all told, with a lot of spaces and is quite readable.&lt;/p&gt;

&lt;p&gt;This handles the same tasks as the old set of scripts did, and it does this without undue complexity. I like it.&lt;/p&gt;</description><link>http://ayende.com/blog/4156/on-psake?key=a139247c-a9eb-49eb-b918-41a87ed8d72c</link><guid>http://ayende.com/blog/4156/on-psake?key=a139247c-a9eb-49eb-b918-41a87ed8d72c</guid><pubDate>Sun, 30 Aug 2009 12:02:48 GMT</pubDate></item><item><title>The complexity of unity</title><description>&lt;p&gt;This post is about the Rhino Tools project. It has been running for a long time now, over 5 years, and amassed quite a few projects in it.&lt;/p&gt;  &lt;p&gt;I really like the codebase in the projects in Rhino Tools, but secondary aspects has been creeping in that made &lt;em&gt;managing&lt;/em&gt; the project harder. In particular, putting all the projects in a single repository made it easy, far &lt;em&gt;too&lt;/em&gt; easy. Projects had an easy time taking dependencies that they shouldn’t, and the entire build process was… complex, to say the least.&lt;/p&gt;  &lt;p&gt;I have been somewhat unhappily tolerant of this so far because while it was annoying, it didn’t actively create problems for me so far. The problems started creeping when I wanted to move Rhino Tools to use NHibernate 2.1. That is when I realized that this is going to be a very painful process, since I have to take on the entire Rhino Tools set of projects in one go, instead of dealing with each of them independently. the fact that so many of the dependencies where in Rhino Commons, to which I have a profound dislike, helped increase my frustration.&lt;/p&gt;  &lt;p&gt;There are other things that I find annoying now, Rhino Security is a general purpose library for NHibernate, but it makes a &lt;em&gt;lot&lt;/em&gt; of assumptions about how it is going to use, which is wrong. Rhino ETL had a dependency on Rhino Commons because of three classes.&lt;/p&gt;  &lt;p&gt;To resolve that, I decided to make a few other changes, taking dependencies is supposed to be a hard process, it is supposed to make you &lt;em&gt;think&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;I have been working on splitting the Rhino Tools projects to all its sub projects, so each of them is independent of all the others. That increase the effort of managing all of them as a unit, but decrease the effort of managing them independently. &lt;/p&gt;  &lt;p&gt;The current goals are to:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Make it simpler to treat each project independently&lt;/li&gt;    &lt;li&gt;Make it easier to deal with the management of each project (dependencies, build scripts)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;There is a side line in which I am also learning to use Git, and there is a high likelihood that the separate Rhino Tools projects will move to github. Suversion’s patching &amp;amp; tracking capabilities annoyed me for the very last time about a week ago.&lt;/p&gt;</description><link>http://ayende.com/blog/4155/the-complexity-of-unity?key=c67b137f-39fe-42a1-990f-815541e1fa4d</link><guid>http://ayende.com/blog/4155/the-complexity-of-unity?key=c67b137f-39fe-42a1-990f-815541e1fa4d</guid><pubDate>Sun, 30 Aug 2009 08:14:42 GMT</pubDate></item><item><title>Common infrastructure? Don't make me laugh</title><description>&lt;p&gt;I am currently in the process of retiring the IRepository&amp;lt;T&amp;gt; from Rhino.Commons. I am moving it to its own set of projects, and I am not going to give it much attention in the future. &lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;strong&gt;Note: &lt;/strong&gt;&lt;em&gt;Backward comparability is maintained, as long as you reference the new DLLs.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;But why am I doing that? If there is anything that I have been thought in the last couple of years is that there is a sharp and clear distinction between technological infrastructure (web frameworks, IoC containers, OR/M) and application infrastructure (layer super type, base services, conventions). The first can and should be made common, but trying to make the application infrastructure shared between multiple projects that aren't closely matched is likely to cause a lot of issues.&lt;/p&gt; &lt;p&gt;To take the IRepository&amp;lt;T&amp;gt; example, it currently have over &lt;em&gt;50&lt;/em&gt; methods. If that isn't a violation of SRP, I don't know what is. Hell, you can even execute a stored procedure using the IRepository&amp;lt;T&amp;gt; infrastructure. That is too much.&lt;/p&gt; &lt;p&gt;What will I use instead? A project focused infrastructure. A repository &lt;em&gt;interface&lt;/em&gt; reflect the application that is using it, and it changes from project to project and even in the same project as our understanding of how the project is built improve.&lt;/p&gt; &lt;p&gt;I am still considering what to do with the other tidbits that I have there, such as the EntitiesToRepositories implementation. Ideally, I want to keep Rhino Commons focused on only session management, and nothing else beside.&lt;/p&gt;</description><link>http://ayende.com/blog/3693/common-infrastructure-dont-make-me-laugh?key=c427bb67-0439-413d-af73-c8cbc26e28e8</link><guid>http://ayende.com/blog/3693/common-infrastructure-dont-make-me-laugh?key=c427bb67-0439-413d-af73-c8cbc26e28e8</guid><pubDate>Thu, 13 Nov 2008 03:22:28 GMT</pubDate></item><item><title>Rhino Queues</title><description>&lt;p&gt;One of the things that often come up in the NServiceBus mailing list is the request for an xcopy, zero administration, queuing service. This is especially the case when you have smart clients or want to have queues over the Internet.&lt;/p&gt;  &lt;p&gt;I decided to try to build such a thing, because it didn't seem such a hard problem. I turned out to be wrong, but it was an interesting experiment. Actually, the problem isn't that it is hard to do this, the problem was that I wanted durable queuing, and that led me to a lot of technologies that weren't suitable for my needs.&lt;/p&gt;  &lt;p&gt;You can get the bits here: &lt;a title="https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/branches/rhino-queues-1.0" href="https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/branches/rhino-queues-1.0"&gt;https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/branches/rhino-queues-1.0&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;What it is:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;XCopyable, Zero Administration, Embedded, Async queuing service&lt;/li&gt;    &lt;li&gt;Robust in the face of networking outages&lt;/li&gt;    &lt;li&gt;System.Transactions support&lt;/li&gt;    &lt;li&gt;Fast&lt;/li&gt;    &lt;li&gt;Works over HTTP&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;What it isn't:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Durable queuing service&lt;/li&gt;    &lt;li&gt;Wetted by production use&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Broadly, using Rhino Queues you get async queues over HTTP. &lt;em&gt;But&lt;/em&gt;, it keeps all the data in memory, so if you restart the application, it will lose all waiting messages. It also tries its best (but does not guarantee) to ensure message ordering and ensure delivery.&lt;/p&gt;  &lt;p&gt;Let us take a look at the code, and then discuss the implementation details from there.&lt;/p&gt;  &lt;p&gt;Server usage:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt;(&lt;font color="#0000ff"&gt;var&lt;/font&gt; factory = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Configuration("&lt;span style="color: #8b0000"&gt;server&lt;/span&gt;")
	.Map("&lt;span style="color: #8b0000"&gt;server&lt;/span&gt;").To("&lt;span style="color: #8b0000"&gt;http://localhost:9999/server/&lt;/span&gt;")
	.Map("&lt;span style="color: #8b0000"&gt;client&lt;/span&gt;").To("&lt;span style="color: #8b0000"&gt;http://localhost:9999/client/&lt;/span&gt;")
	.RegisterQueue("&lt;span style="color: #8b0000"&gt;echo&lt;/span&gt;")
	.BuildQueueFactory())
{
&lt;br /&gt;	factory.Start();&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (&lt;font color="#0000ff"&gt;var&lt;/font&gt; queue = factory.OpenQueue("&lt;span style="color: #8b0000"&gt;echo&lt;/span&gt;"))
	{
		&lt;font color="#0000ff"&gt;var&lt;/font&gt; message = queue.Recieve();
		&lt;font color="#0000ff"&gt;var&lt;/font&gt; str = (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;)message.Value;
		&lt;font color="#0000ff"&gt;var&lt;/font&gt; rev = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;(str.Reverse().ToArray());
		&lt;span style="color: #0000ff"&gt;using&lt;/span&gt;(&lt;font color="#0000ff"&gt;var&lt;/font&gt; remoteQueue = factory.OpenQueue(message.Source))
		{	
			Console.WriteLine("&lt;span style="color: #8b0000"&gt;Handled message&lt;/span&gt;");
			remoteQueue.Send(rev);
		}
	}
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;And the client usage:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt;(&lt;font color="#0000ff"&gt;var&lt;/font&gt; factory = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Configuration("&lt;span style="color: #8b0000"&gt;client&lt;/span&gt;")
	.Map("&lt;span style="color: #8b0000"&gt;server&lt;/span&gt;").To("&lt;span style="color: #8b0000"&gt;http://localhost:9999/server/&lt;/span&gt;")
	.Map("&lt;span style="color: #8b0000"&gt;client&lt;/span&gt;").To("&lt;span style="color: #8b0000"&gt;http://localhost:9999/client/&lt;/span&gt;")
	.RegisterQueue("&lt;span style="color: #8b0000"&gt;echo-reply&lt;/span&gt;")
	.BuildQueueFactory())
{

	factory.Start();

	&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (&lt;font color="#0000ff"&gt;var&lt;/font&gt; tx = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TransactionScope())
	&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (&lt;font color="#0000ff"&gt;var&lt;/font&gt; serverQueue = factory.OpenQueue("&lt;span style="color: #8b0000"&gt;echo@server&lt;/span&gt;"))
	{
		Console.WriteLine("&lt;span style="color: #8b0000"&gt;Sending 'hello there'&lt;/span&gt;");
		serverQueue.Send("&lt;span style="color: #8b0000"&gt;Hello there&lt;/span&gt;").Source = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Destination("&lt;span style="color: #8b0000"&gt;echo-reply@client&lt;/span&gt;");
		tx.Complete();
	}
	
	&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (&lt;font color="#0000ff"&gt;var&lt;/font&gt; clientQueue = factory.OpenQueue("&lt;span style="color: #8b0000"&gt;echo-reply&lt;/span&gt;"))
	{
		var msgText = clientQueue.Recieve();
		Console.WriteLine(msgText.Value);
	}
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;As you can see, we map a nice name to an endpoint, so we can send message to [queue]@[endpoint nice name], sending a message to just [queue] send it to the local machine. It is expected that the nice name for an endpoint would be the machine name, which alleviate the need of syncing names across all endpoints.&lt;/p&gt;

&lt;p&gt;You can also see the usage of System.Transaction and without System.Transactions.&lt;/p&gt;

&lt;p&gt;One thing that would probably raise questions is why Rhino Queues doesn't have a durable mode, after all, I just spent some time building a &lt;a href="http://www.ayende.com/Blog/archive/2008/08/01/Rhino.Queues.Storage.Disk.aspx"&gt;durable queue infrastructure&lt;/a&gt;. The reason for that is very simple, I spent too much time on that, and I can't spend more time on this at the moment. So I am putting both Rhino Queues and Rhino Queues Storage Disk out there, and I'll let the community bring them together.&lt;/p&gt;

&lt;p&gt;A word of warning, Rhino Queues is a cool project, but it is not a replacement for such things as MSMQ. If you can, you probably want to make use of MSMQ, specifically because there is a lot more production time using it.&lt;/p&gt;</description><link>http://ayende.com/blog/3480/rhino-queues?key=34cebd1e-0519-41f9-b9b1-448ddd9825ba</link><guid>http://ayende.com/blog/3480/rhino-queues?key=34cebd1e-0519-41f9-b9b1-448ddd9825ba</guid><pubDate>Fri, 01 Aug 2008 19:22:30 GMT</pubDate></item><item><title>The purpose of Rhino Commons</title><description>&lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://hsidev.wordpress.com/"&gt;Nathan&lt;/a&gt; has posted about &lt;a href="http://hsidev.wordpress.com/2008/07/15/net-utility-libraries-galore/"&gt;utility libraries&lt;/a&gt; and he includes Rhino Commons there as well.&lt;/p&gt;  &lt;p&gt;I don't see Rhino Commons as a utility library. At least not anymore. It certainly started its life as such, but it has grown since then.&lt;/p&gt;  &lt;p&gt;Rhino Commons represent my default architecture. This is my base when I am building applications. It has some utility classes, sure, but it contains a lot more foundation and infrastructure components than anything else.&lt;/p&gt;</description><link>http://ayende.com/blog/3420/the-purpose-of-rhino-commons?key=37372027-be48-421c-96cd-7bfc031c4cff</link><guid>http://ayende.com/blog/3420/the-purpose-of-rhino-commons?key=37372027-be48-421c-96cd-7bfc031c4cff</guid><pubDate>Fri, 18 Jul 2008 08:55:37 GMT</pubDate></item><item><title>Answer: How many tests?</title><description>&lt;p&gt;Two days ago I asked &lt;a href="http://www.ayende.com/Blog/archive/2008/06/10/How-many-tests.aspx"&gt;how many tests&lt;/a&gt; this method need:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre&gt;&lt;span style="color: #808080"&gt;///&amp;lt;summary&amp;gt; &lt;/span&gt;
&lt;span style="color: #808080"&gt;///Get the latest published webcast &lt;/span&gt;
&lt;span style="color: #808080"&gt;///&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Webcast GetLatest();&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here is what I came up with:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre&gt;[TestFixture]
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; WebcastRepositoryTest : DatabaseTestFixtureBase
{
	&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; IWebcastRepository webcastRepository;

	[TestFixtureSetUp]
	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; TestFixtureSetup()
	{
		IntializeNHibernateAndIoC(PersistenceFramework.ActiveRecord, 
			"&lt;span style="color: #8b0000"&gt;windsor.boo&lt;/span&gt;", MappingInfo.FromAssemblyContaining&amp;lt;Webcast&amp;gt;());
	}

	[SetUp]
	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Setup()
	{
		CurrentContext.CreateUnitOfWork();
		webcastRepository = IoC.Resolve&amp;lt;IWebcastRepository&amp;gt;();
	}

	[TearDown]
	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Teardown()
	{
		CurrentContext.DisposeUnitOfWork();
	}

	[Test]
	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Can_save_webcast()
	{
		var webcast = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Webcast { Name = "&lt;span style="color: #8b0000"&gt;test&lt;/span&gt;", PublishDate = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; };
		With.Transaction(() =&amp;gt; webcastRepository.Save(webcast));
		Assert.AreNotEqual(0, webcast.Id);
	}

	[Test]
	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Can_load_webcast()
	{
		var webcast = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Webcast { Name = "&lt;span style="color: #8b0000"&gt;test&lt;/span&gt;", PublishDate = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; };
		With.Transaction(() =&amp;gt; webcastRepository.Save(webcast));
		UnitOfWork.CurrentSession.Evict(webcast);

		var webcast2 = webcastRepository.Get(webcast.Id);
		Assert.AreEqual(webcast.Id, webcast2.Id);
		Assert.AreEqual("&lt;span style="color: #8b0000"&gt;test&lt;/span&gt;", webcast2.Name);
		Assert.IsNull(webcast2.PublishDate);
	}

	[Test]
	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; When_asking_for_latest_webcast_will_not_consider_any_that_is_not_published()
	{
		var webcast = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Webcast { Name = "&lt;span style="color: #8b0000"&gt;test&lt;/span&gt;", PublishDate = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; };
		With.Transaction(() =&amp;gt; webcastRepository.Save(webcast));

		Assert.IsNull(webcastRepository.GetLatest());
	}

	[Test]
	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; When_asking_for_latest_webcast_will_get_published_webcast()
	{
		var webcast = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Webcast { Name = "&lt;span style="color: #8b0000"&gt;test&lt;/span&gt;", PublishDate = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; };
		With.Transaction(() =&amp;gt; webcastRepository.Save(webcast));
		var webcast2 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Webcast { Name = "&lt;span style="color: #8b0000"&gt;test&lt;/span&gt;", PublishDate = DateTime.Now.AddDays(-1) };
		With.Transaction(() =&amp;gt; webcastRepository.Save(webcast2));

		Assert.AreEqual(webcast2.Id, webcastRepository.GetLatest().Id);
	}

	[Test]
	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; When_asking_for_latest_webcast_will_get_the_latest_webcast()
	{
		var webcast = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Webcast { Name = "&lt;span style="color: #8b0000"&gt;test&lt;/span&gt;", PublishDate = DateTime.Now.AddDays(-2) };
		With.Transaction(() =&amp;gt; webcastRepository.Save(webcast));
		var webcast2 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Webcast { Name = "&lt;span style="color: #8b0000"&gt;test&lt;/span&gt;", PublishDate = DateTime.Now.AddDays(-1) };
		With.Transaction(() =&amp;gt; webcastRepository.Save(webcast2));

		Assert.AreEqual(webcast2.Id, webcastRepository.GetLatest().Id);
	}

	[Test]
	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; When_asking_for_latest_webcast_will_not_consider_webcasts_published_in_the_future()
	{
		var webcast = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Webcast { Name = "&lt;span style="color: #8b0000"&gt;test&lt;/span&gt;", PublishDate = DateTime.Now.AddDays(-2) };
		With.Transaction(() =&amp;gt; webcastRepository.Save(webcast));
		var webcast2 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Webcast { Name = "&lt;span style="color: #8b0000"&gt;test&lt;/span&gt;", PublishDate = DateTime.Now.AddDays(2) };
		With.Transaction(() =&amp;gt; webcastRepository.Save(webcast2));
		Assert.AreEqual(webcast.Id, webcastRepository.GetLatest().Id);
	}
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;And the implementation:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; WebcastRepository : RepositoryDecorator&amp;lt;Webcast&amp;gt;, IWebcastRepository
{
	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; WebcastRepository(IRepository&amp;lt;Webcast&amp;gt; repository)
	{
		Inner = repository;
	}

	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Webcast GetLatest()
	{
		&lt;font color="#0000ff"&gt;var&lt;/font&gt; publishedWebcastsByDateDesc =
			&lt;font color="#0000ff"&gt;from&lt;/font&gt; webcast &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; Webcasts
			&lt;font color="#0000ff"&gt;where&lt;/font&gt; webcast.PublishDate != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; webcast.PublishDate &amp;lt; SystemTime.Now()
			&lt;font color="#0000ff"&gt;orderby&lt;/font&gt; webcast.PublishDate descending 
			&lt;font color="#0000ff"&gt;select&lt;/font&gt; webcast;

		&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; publishedWebcastsByDateDesc.FirstOrDefault();
	}

	&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; IOrderedQueryable&amp;lt;Webcast&amp;gt; Webcasts
	{
		&lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; UnitOfWork.CurrentSession.Linq&amp;lt;Webcast&amp;gt;(); }
	}
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;I think it is pretty sweet.&lt;/p&gt;</description><link>http://ayende.com/blog/3361/answer-how-many-tests?key=c75f124d-588e-4066-b3e0-49f4bd1ff4d4</link><guid>http://ayende.com/blog/3361/answer-how-many-tests?key=c75f124d-588e-4066-b3e0-49f4bd1ff4d4</guid><pubDate>Thu, 12 Jun 2008 09:52:33 GMT</pubDate></item><item><title>Adaptive Domain Models with Rhino Commons</title><description>&lt;p&gt;&lt;a href="http://udidahan.weblogs.us/"&gt;Udi Dahan&lt;/a&gt; has &lt;a href="http://udidahan.weblogs.us/2007/09/16/fetching-strategy-nhibernate-implementation-available/"&gt;been&lt;/a&gt; &lt;a href="http://udidahan.weblogs.us/2008/03/20/qcon-london-2008-recap/"&gt;talking&lt;/a&gt; &lt;a href="http://udidahan.weblogs.us/2007/04/23/fetching-strategy-design/"&gt;about&lt;/a&gt; this for &lt;a href="http://udidahan.weblogs.us/2007/03/06/better-domain-driven-design-implementation/"&gt;a while now&lt;/a&gt;. As usual, he makes sense, but I am working in different enough context that it takes time to assimilate it.&lt;/p&gt;  &lt;p&gt;At any rate, we have been talking about this for a few days, and I finally sat down and decided that I really need to look at it with code. The result of that experiment is that I like this approach, but am still not 100% sold. &lt;/p&gt;  &lt;p&gt;The first idea is that we need to decouple the service layer from our domain implementation. But why? The domain layer is under the service layer, after all. Surely the service layer should be able to reference the domain. The reasoning here is that the domain model play several different roles in most applications. It is the preferred way to access our persistent information (but they should not be aware of persistence), it is the central place for business logic, it is the representation of our notions about the domain, and much more that I am probably leaving aside.&lt;/p&gt;  &lt;p&gt;The problem here is there is a dissonance between the requirements we have here. Let us take a simple example of an Order entity.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/AdaptiveDomainModelswithRhinoCommons_9E6D/image_2.png"&gt;&lt;img style="margin: 0px 15px 0px 0px" height="143" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/AdaptiveDomainModelswithRhinoCommons_9E6D/image_thumb.png" width="163" align="left" border="0" /&gt;&lt;/a&gt; As you can see, Order has several things that I can do. It can accept an new line, and it can calculate the total cost of the order.&lt;/p&gt;  &lt;p&gt;But those are two distinct responsibilities that are based on the same entity. What is more, they have completely different persistence related requirements.&lt;/p&gt;  &lt;p&gt;I talked about this issue &lt;a href="http://www.ayende.com/Blog/archive/9042.aspx"&gt;here&lt;/a&gt;, over a year ago. &lt;/p&gt;  &lt;p&gt;So, we need to split the responsibilities, so we can take care of each of them independently. But it doesn't make sense to split the Order entity, so instead we will introduce purpose driven interfaces. Now, when we want to talk about the domain, we can view certain aspect of the Order entity in isolation.&lt;/p&gt;  &lt;p&gt;This leads us to the following design:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/AdaptiveDomainModelswithRhinoCommons_9E6D/image_4.png"&gt;&lt;img height="185" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/AdaptiveDomainModelswithRhinoCommons_9E6D/image_thumb_1.png" width="355" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;And now we can refer to the separate responsibilities independently. Doing this based on the type open up to the &lt;a href="http://www.ayende.com/Blog/archive/2008/03/25/Non-Invasive-API-take-2.aspx"&gt;non invasive API&lt;/a&gt; &lt;a href="http://www.ayende.com/Blog/archive/2008/03/19/Non-invasive-API--Now-with-an-IoC-container.aspx"&gt;approaches&lt;/a&gt; that I talked about &lt;a href="http://www.ayende.com/Blog/archive/2008/03/19/Avoiding-Invasive-API-design.aspx"&gt;before&lt;/a&gt;. You can read Udi's posts about it to learn more about the concepts. Right now I am more interested in discussing the implementation.&lt;/p&gt;  &lt;p&gt;First, the unit of abstraction that we work in is the IRepository&amp;lt;T&amp;gt;, as always. &lt;/p&gt;  &lt;p&gt;The major change with introducing the idea of a ConcreteType to the repository. Now it will try to use the ConcreteType instead of the give typeof(T) that it was created with. This affects all queries done with the repository (of course, if you don't specify ConcreteType, nothing changes).&lt;/p&gt;  &lt;p&gt;The repository got a single new method:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;T Create();&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This allows you to create new instances of the entity without knowing its concrete type. And that is basically it. &lt;/p&gt;  &lt;p&gt;Well, not really :-)&lt;/p&gt;  &lt;p&gt;I introduced two other concepts as well.&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IFetchingStrategy&amp;lt;T&amp;gt;
{
	ICriteria Apply(ICriteria criteria);
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;IFetchingStrategy can interfere in the way queries are constructed. As a simple example, you could build a strategy that force eager load of the OrderLines collection when the IOrderCostCalculator is being queried.&lt;/p&gt;

&lt;p&gt;There is not complex configuration involved in setting up IFetchingStrategy. All you need to do is register your strategies in the container, and let the repository do the rest.&lt;/p&gt;

&lt;p&gt;However, doesn't this mean that we now need to explicitly register repositories for all our entities (and for all their interfaces)?&lt;/p&gt;

&lt;p&gt;Well, yes, but no. Technically we need to do that. But we have help, EntitiesToRepositories.Register, so we can just put the following line somewhere in the application startup and we are done.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre&gt;EntitiesToRepositories.Register(
	IoC.Container, 
	UnitOfWork.CurrentSession.SessionFactory, 
	&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt; (NHRepository&amp;lt;&amp;gt;),
	&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt; (IOrderCostCalculator).Assembly);&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;And this is it, you can start working with this new paradigm with no extra steps.&lt;/p&gt;

&lt;p&gt;As a side benefit, this really pave the way to complex multi tenant applications. &lt;/p&gt;</description><link>http://ayende.com/blog/3219/adaptive-domain-models-with-rhino-commons?key=e59e51e7-2e82-4e4c-88f0-6d4e747cdd0c</link><guid>http://ayende.com/blog/3219/adaptive-domain-models-with-rhino-commons?key=e59e51e7-2e82-4e4c-88f0-6d4e747cdd0c</guid><pubDate>Thu, 27 Mar 2008 09:16:19 GMT</pubDate></item><item><title>Dealing with hierarchical structures in databases</title><description>&lt;p&gt;I have a very simple requirement, I need to create a hierarchy of users' groups. So you can do something like:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Administrators&lt;/li&gt; &lt;ul&gt; &lt;li&gt;DBA&lt;/li&gt; &lt;ul&gt; &lt;li&gt;SQLite DBA&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;/ul&gt; &lt;p&gt;If you are a member of SQLite DBA group, you are implicitly a member of the Administrators group.&lt;/p&gt; &lt;p&gt;In the database, it is trivial to model this:&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/360903dea804_8BD/image_4.png"&gt;&lt;img height="155" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/360903dea804_8BD/image_thumb_1.png" width="264" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Except that then we run into the problem of dealing with the hierarchy. We can't really ask questions that involve more than one level of the hierarchy easily.  Some databases has support for hierarchical operators, but that is different from one database to the next. That is a problem, since I need it to work across databases, and without doing too much fancy stuff.&lt;/p&gt; &lt;p&gt;We can work around the problem by introducing a new table:&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/360903dea804_8BD/image_6.png"&gt;&lt;img height="157" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/360903dea804_8BD/image_thumb_2.png" width="621" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Now we move the burden of the hierarchy from the query phase to the data entry phase. &lt;/p&gt; &lt;p&gt;From the point of view of the entity, we have this:&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/360903dea804_8BD/image_8.png"&gt;&lt;img height="161" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/360903dea804_8BD/image_thumb_3.png" width="353" border="0" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Please ignore the death star shape and concentrate on the details :-) &lt;/p&gt; &lt;p&gt;Here is how we are getting all the data in the tree:&lt;/p&gt; &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; UsersGroup[] GetAssociatedUsersGroupFor(IUser user)
{
    DetachedCriteria directGroupsCriteria = DetachedCriteria.For&amp;lt;UsersGroup&amp;gt;()
        .CreateAlias("&lt;span style="color: #8b0000"&gt;Users&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;user&lt;/span&gt;")
        .Add(Expression.Eq("&lt;span style="color: #8b0000"&gt;user.id&lt;/span&gt;", user.SecurityInfo.Identifier))
        .SetProjection(Projections.Id());

    DetachedCriteria allGroupsCriteria = DetachedCriteria.For&amp;lt;UsersGroup&amp;gt;()
        .CreateAlias("&lt;span style="color: #8b0000"&gt;Users&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;user&lt;/span&gt;", JoinType.LeftOuterJoin)
        .CreateAlias("&lt;span style="color: #8b0000"&gt;AllChildren&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;child&lt;/span&gt;", JoinType.LeftOuterJoin)
        .Add(
            Subqueries.PropertyIn("&lt;span style="color: #8b0000"&gt;child.id&lt;/span&gt;", directGroupsCriteria) ||
            Expression.Eq("&lt;span style="color: #8b0000"&gt;user.id&lt;/span&gt;", user.SecurityInfo.Identifier));

    ICollection&amp;lt;UsersGroup&amp;gt; usersGroups = 
        usersGroupRepository.FindAll(allGroupsCriteria, Order.Asc("&lt;span style="color: #8b0000"&gt;Name&lt;/span&gt;"));
    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Collection.ToArray&amp;lt;UsersGroup&amp;gt;(usersGroups);
}
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Note that here we don't care whatever we are associated with a group directly or indirectly. This is an important consideration in some scenarios (mostly when you want to display information to the user), so we need some way to chart the hierarchy, right?&lt;/p&gt;
&lt;p&gt;Here is how we are doing this:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; UsersGroup[] GetAncestryAssociation(IUser user, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; usersGroupName)
{
    UsersGroup desiredGroup = GetUsersGroupByName(usersGroupName);
    ICollection&amp;lt;UsersGroup&amp;gt; directGroups =
        usersGroupRepository.FindAll(GetDirectUserGroupsCriteria(user));
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (directGroups.Contains(desiredGroup))
    {
        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; UsersGroup[] { desiredGroup };
    }
    &lt;span style="color: #008000"&gt;// as a nice benefit, this does an eager load of all the groups in the hierarchy&lt;/span&gt;
    &lt;span style="color: #008000"&gt;// in an efficient way, so we don't have SELECT N + 1 here, nor do we need&lt;/span&gt;
    &lt;span style="color: #008000"&gt;// to load the Users collection (which may be very large) to check if we are associated&lt;/span&gt;
    &lt;span style="color: #008000"&gt;// directly or not&lt;/span&gt;
    UsersGroup[] associatedGroups = GetAssociatedUsersGroupFor(user);
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Array.IndexOf(associatedGroups, desiredGroup) == -1)
    {
        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; UsersGroup[0];
    }
    &lt;span style="color: #008000"&gt;// now we need to find out the path to it&lt;/span&gt;
    List&amp;lt;UsersGroup&amp;gt; shortest = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;UsersGroup&amp;gt;();
    &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (UsersGroup usersGroup &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; associatedGroups)
    {
        List&amp;lt;UsersGroup&amp;gt; path = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;UsersGroup&amp;gt;();
        UsersGroup current = usersGroup;
        &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (current.Parent != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; current != desiredGroup)
        {
            path.Add(current);
            current = current.Parent;
        }
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (current != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
            path.Add(current);
        &lt;span style="color: #008000"&gt;// Valid paths are those that are contains the desired group&lt;/span&gt;
        &lt;span style="color: #008000"&gt;// and start in one of the groups that are directly associated&lt;/span&gt;
        &lt;span style="color: #008000"&gt;// with the user&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (path.Contains(desiredGroup) &amp;amp;&amp;amp; directGroups.Contains(path[0]))
        {
            shortest = Min(shortest, path);
        }
    }
    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; shortest.ToArray();
}&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;As an aside, this is about as complex a method as I can tolerate, and even that just barely.&lt;/p&gt;
&lt;p&gt;I mentioned that the burden was when creating it, right? Here is what I meant:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; UsersGroup CreateChildUserGroupOf(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; parentGroupName, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; usersGroupName)
{
    UsersGroup parent = GetUsersGroupByName(parentGroupName);
    Guard.Against&amp;lt;ArgumentException&amp;gt;(parent == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;,
                                     "&lt;span style="color: #8b0000"&gt;Parent users group '&lt;/span&gt;" + parentGroupName + "&lt;span style="color: #8b0000"&gt;' does not exists&lt;/span&gt;");

    UsersGroup group = CreateUsersGroup(usersGroupName);
    group.Parent = parent;
    group.AllParents.AddAll(parent.AllParents);
    group.AllParents.Add(parent);
    parent.Directchildren.Add(group);
    parent.AllChildren.Add(group);
    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; group;
}&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;We could hide it all inside the Parent's property setter, but we still need to deal with it.&lt;/p&gt;
&lt;p&gt;And that is all you need to do in order to get it cross database hierarchical structures working.&lt;/p&gt;</description><link>http://ayende.com/blog/3107/dealing-with-hierarchical-structures-in-databases?key=de553fdb-d635-46f7-af06-ec7a42eb473d</link><guid>http://ayende.com/blog/3107/dealing-with-hierarchical-structures-in-databases?key=de553fdb-d635-46f7-af06-ec7a42eb473d</guid><pubDate>Mon, 21 Jan 2008 23:49:47 GMT</pubDate></item><item><title>Rhino Igloo – MVC Framework for Web Forms</title><description>&lt;p&gt;How many times have the documentation of a product told you that you really should use another product? Well, this is one such case. Rhino Igloo is an attempt to make an application that was mandated to Web Forms more palatable to work with. As such, it is heavily influenced by MonoRail and its ideas. &lt;/p&gt; &lt;p&gt;I speak as the creator of this framework, if at all possible, prefer (mandate!) the use of MonoRail, it will be far easier, all around.&lt;/p&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;Model View Controller is a problematic subject in Web Forms, because of the importance placed on the view (ASPX page) in the Web Forms framework.&lt;/p&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;When coming to build an MVC framework on top of Web Forms, we need to consider this limitation in our design. For that reason, Rhino Igloo is not a pure MVC framework, and it works under the limitations of the Web Forms framework.&lt;/p&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;Along with the MVC framework, Rhino Igloo has tight integration to the Windsor IoC container, and make extensive use of it in its internal operations.&lt;/p&gt; &lt;div style="border-right: medium none; padding-right: 0in; border-top: medium none; padding-left: 0in; padding-bottom: 4pt; margin-left: 0.65in; border-left: medium none; margin-right: 0.65in; padding-top: 0in; border-bottom: #4f81bd 1pt solid; mso-element: para-border-div; mso-border-bottom-alt: solid #4f81bd .5pt"&gt; &lt;p class="MsoIntenseQuote" style="margin: 10pt 0in 14pt; direction: ltr; unicode-bidi: embed; text-align: left"&gt;It is important to note that while we cover the main chain of events that occurs when using Rhino Igloo, we are not going into the implementation details here, just a broad usage overview.&lt;/p&gt;I took to liberty of flat out ignoring implementation details that are not necessary to understanding how things flow.&lt;/div&gt; &lt;h3 style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;&lt;a name="_Toc176597326"&gt;&lt;span style="mso-bookmark: _toc176597407"&gt;The Views&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;&lt;img height="198" hspace="12" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/RhinoIglooMVCFrameworkforWebForms_139AE/clip_image002_2.jpg" width="259" align="right" v:shapes="Picture_x0020_3" /&gt;Overall, the Rhino Igloo4framework hooks into the Web Forms pipeline by utilizing a common set of base classes ( BasePage, BaseMaster, BaseScriptService, BaseHttpHandler ).&lt;span style="mso-spacerun: yes"&gt;  &lt;/span&gt;This set of base classes provide transparent dependency injection capabilities to the views.&lt;/p&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;As an example, to the right you can see the Login page. As you can see that the login page has a Controller property, of type LoginController. The controller property is a simple property, which the base page initializes with an instance of the LoginController.&lt;/p&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;It is important to note that it is &lt;i&gt;not&lt;/i&gt; the responsibility of the Login page to initialize the Controller property, but rather its parent, the BasePage. As an example, here is a valid page, which, when run, will have its Controller property set to an instance of a LoginController:&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"&gt;public&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt; &lt;span style="color: blue"&gt;partial&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Login&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;BasePage&lt;?xml:namespace prefix = o /?&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;    &lt;/span&gt;&lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;LoginController&lt;/span&gt; controller;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;    &lt;/span&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;LoginController&lt;/span&gt; Controller&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;    &lt;/span&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;        &lt;/span&gt;&lt;span style="color: blue"&gt;get&lt;/span&gt; { &lt;span style="color: blue"&gt;return&lt;/span&gt; controller; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;        &lt;/span&gt;&lt;span style="color: blue"&gt;set&lt;/span&gt; { controller = &lt;span style="color: blue"&gt;value&lt;/span&gt;; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;&lt;span style="font-size: 10pt; line-height: 115%; font-family: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;    &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;&lt;span style="mso-spacerun: yes"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; line-height: 115%; font-family: 'Courier New'; mso-no-proof: yes"&gt;}&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;As a result of that, the view no longer needs to be aware of the dependencies that the LoginController itself has. Those are automatically supplied using Windsor itself.&lt;/p&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;The controller is the one responsible for handling the logic of the particular use case that we need to handle. The view's responsibilities are to call the controller when needed. Here is the full implementation of the above Login_Click method:&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"&gt;public&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Logon_Click(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt; e)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;    &lt;/span&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt; (!Controller.Authenticate(Username.Text, Password.Text))&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;    &lt;/span&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;    &lt;/span&gt;&lt;span style="mso-tab-count: 1"&gt;  &lt;/span&gt;lblError.Text = &lt;span style="color: #2b91af"&gt;Scope&lt;/span&gt;.ErrorMessage;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;    &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;As you can see, the view calls to the controller, which can communicate back to the view using the scope. &lt;/p&gt; &lt;h3 style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;&lt;img height="223" hspace="12" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/RhinoIglooMVCFrameworkforWebForms_139AE/clip_image004_2.jpg" width="283" align="right" v:shapes="Picture_x0020_4" /&gt;&lt;a name="_Toc176597408"&gt;&lt;/a&gt;&lt;a name="_Toc176597327"&gt;&lt;span style="mso-bookmark: _toc176597408"&gt;The Scope&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;The scope class is the main way controllers get their data, and a common way to pass results from the controller to the view.&lt;/p&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;The scope class contains properties such as Input and Session, which allows an abstract access to the current request and the user's session.&lt;/p&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;This also allows replacing them when testing, so we can test the behavior of the controllers without resorting to loading the entire HTTP pipeline.&lt;/p&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;Of particular interest are the following properties:&lt;/p&gt; &lt;p class="MsoListParagraphCxSpFirst" style="margin: 0in 0in 10pt 0.5in; direction: ltr; text-indent: -0.25in; unicode-bidi: embed; text-align: left; mso-add-space: auto; mso-list: l0 level1 lfo1"&gt;&lt;span style="font-family: symbol; mso-fareast-font-family: symbol; mso-bidi-font-family: symbol"&gt;&lt;span style="mso-list: ignore"&gt;·&lt;span style="font: 7pt 'Times New Roman'"&gt;         &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span dir="ltr"&gt;&lt;/span&gt;Scope.ErrorMessage&lt;/p&gt; &lt;p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 10pt 0.5in; direction: ltr; text-indent: -0.25in; unicode-bidi: embed; text-align: left; mso-add-space: auto; mso-list: l0 level1 lfo1"&gt;&lt;span style="font-family: symbol; mso-fareast-font-family: symbol; mso-bidi-font-family: symbol"&gt;&lt;span style="mso-list: ignore"&gt;·&lt;span style="font: 7pt 'Times New Roman'"&gt;         &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span dir="ltr"&gt;&lt;/span&gt;Scope.SuccessMessage&lt;/p&gt; &lt;p class="MsoListParagraphCxSpLast" style="margin: 0in 0in 10pt 0.5in; direction: ltr; text-indent: -0.25in; unicode-bidi: embed; text-align: left; mso-add-space: auto; mso-list: l0 level1 lfo1"&gt;&lt;span style="font-family: symbol; mso-fareast-font-family: symbol; mso-bidi-font-family: symbol"&gt;&lt;span style="mso-list: ignore"&gt;·&lt;span style="font: 7pt 'Times New Roman'"&gt;         &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span dir="ltr"&gt;&lt;/span&gt;Scope.ErrorSummary&lt;/p&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;These allow the controller to pass messages to the view, and in the last case, the entire validation failure package, as a whole.&lt;/p&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;Communication between the controller and the view is intentionally limited, in order to ensure separation of concerns between the two.&lt;/p&gt;&lt;b&gt;&lt;span style="font-size: 13pt; line-height: 115%; font-family: 'Cambria','serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: en-us; mso-fareast-language: en-us; mso-bidi-language: he"&gt;&lt;br style="page-break-before: always" clear="all" /&gt;&lt;/span&gt;&lt;/b&gt; &lt;h3 style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;&lt;a name="_Toc176597409"&gt;&lt;/a&gt;&lt;a name="_Toc176597328"&gt;&lt;span style="mso-bookmark: _toc176597409"&gt;The controllers&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;&lt;img height="370" hspace="12" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/RhinoIglooMVCFrameworkforWebForms_139AE/clip_image006_2.jpg" width="259" align="right" v:shapes="Picture_x0020_5" /&gt;All controllers inherit from Base Controller, which serves as a common base class and a container for a set of utility methods as well.&lt;/p&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;From the controller, we can access the current context, which is a nicer wrapper around the Http Context and operations exposed by it.&lt;/p&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;While the controllers are POCO classes, which are easily instantiated and used outside the HTTP context, there are a few extra niceties that are supplied for the controllers.&lt;/p&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;The first is the Initalize() method, which allows the controller to initialize itself before processing begins. &lt;/p&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;As an extension to this idea, and taking from MonoRail DataBind approach, there are other niceties: &lt;/p&gt; &lt;h4 style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;[Inject]&lt;/h4&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;Inject is an attribute that can be used to decorate a property, at which point the Rhino Igloo framework will take a value from the request, convert it to the appropriate data type and set the property when the controller is first being created. Here is an example:&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;[&lt;span style="color: #2b91af"&gt;Inject&lt;/span&gt;]&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"&gt;public&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt; &lt;span style="color: blue"&gt;virtual&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Guid&lt;/span&gt; CurrentGuid&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;    &lt;/span&gt;&lt;span style="color: blue"&gt;Get&lt;/span&gt; { &lt;span style="color: blue"&gt;return&lt;/span&gt; currentGuid;&lt;span style="mso-spacerun: yes"&gt;  &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;    &lt;/span&gt;&lt;span style="color: blue"&gt;set&lt;/span&gt; { currentGuid = &lt;span style="color: blue"&gt;value&lt;/span&gt;; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;The framework will search for a request parameter with the key "CurrentGuid", convert the string value to a Guid, and set its value.&lt;/p&gt; &lt;h4 style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;[InjectEntity]&lt;/h4&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;InjectEntity performs the same operation as Inject does, but it takes the value and queries the database an entity with the specified key.&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;[&lt;span style="color: #2b91af"&gt;InjectEntity&lt;/span&gt;(Name = &lt;span style="color: #2b91af"&gt;Constants&lt;/span&gt;.Id, EagerLoad = &lt;span style="color: #a31515"&gt;"Customer"&lt;/span&gt;)]&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"&gt;public&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt; &lt;span style="color: #2b91af"&gt;Order&lt;/span&gt; Order&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;    &lt;/span&gt;&lt;span style="color: blue"&gt;get&lt;/span&gt; { &lt;span style="color: blue"&gt;return&lt;/span&gt; order; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;    &lt;/span&gt;&lt;span style="color: blue"&gt;set&lt;/span&gt; { order = &lt;span style="color: blue"&gt;value&lt;/span&gt;; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; direction: ltr; line-height: normal; unicode-bidi: embed; text-align: left; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;This example shows how we can automatically load an order from the database based on the "Id" request parameter, and eager load the Customer property as well.&lt;/p&gt; &lt;h3 style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;&lt;a name="_Toc176597410"&gt;&lt;/a&gt;&lt;a name="_Toc176597329"&gt;&lt;span style="mso-bookmark: _toc176597410"&gt;The model&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt; &lt;p class="MsoNormal" style="direction: ltr; unicode-bidi: embed; text-align: left"&gt;Rhino Igloo has integration to Rhino Common's Unit Of Work style, but overall, has no constraints on the way the model is built.&lt;/p&gt;</description><link>http://ayende.com/blog/2756/rhino-igloo-mvc-framework-for-web-forms?key=3786d587-399c-4e0c-a94c-ccbe583e3c84</link><guid>http://ayende.com/blog/2756/rhino-igloo-mvc-framework-for-web-forms?key=3786d587-399c-4e0c-a94c-ccbe583e3c84</guid><pubDate>Mon, 03 Sep 2007 19:20:38 GMT</pubDate></item><item><title>Running on the trunk: Building Rhino Commons</title><description>&lt;p&gt;Well, it looks like I have to &lt;a href="http://blogs.chayachronicles.com/sonofnun/archive/2007/08/01/266.aspx"&gt;share the big secret&lt;/a&gt; of how to keep Rhino Commons in sync with both NHibernate &amp;amp; Castle. The secret is never opening Visual Studio and doing it all from the command line. Here is the magic formula:&lt;/p&gt;&lt;pre&gt;D:\OSS&amp;gt;cd nhibernate
D:\OSS\nhibernate&amp;gt;svn up
D:\OSS\nhibernate&amp;gt;nant
D:\OSS\nhibernate&amp;gt;cd..
D:\OSS&amp;gt;cd Castle
D:\OSS\Castle&amp;gt;svn up
D:\OSS\Castle&amp;gt;nant
D:\OSS\Castle&amp;gt;copy ..\nhibernate\build\NHibernate-2.0.0.Alpha1-debug\bin\net-2.0\*.* build\net-2.0\debug /y
D:\OSS\Castle&amp;gt;nant
D:\OSS\Castle&amp;gt;copy ..\nhibernate\build\NHibernate-2.0.0.Alpha1-debug\bin\net-2.0\*.* ..\rhino-tools\SharedLibs\NHibernate /y
D:\OSS\Castle&amp;gt;copy build\net-2.0\debug\*.* ..\rhino-tools\SharedLibs\Castle\*.* /y
D:\OSS\Castle&amp;gt;cd..
D:\OSS&amp;gt;cd rhino-tools
D:\OSS\rhino-tools&amp;gt;msbuild BuildAll.build&lt;/pre&gt;</description><link>http://ayende.com/blog/2687/running-on-the-trunk-building-rhino-commons?key=622b1acf-58d0-417e-8bac-2529b78de497</link><guid>http://ayende.com/blog/2687/running-on-the-trunk-building-rhino-commons?key=622b1acf-58d0-417e-8bac-2529b78de497</guid><pubDate>Mon, 06 Aug 2007 05:06:47 GMT</pubDate></item><item><title>Rhino ETL: Thinking about Joins &amp; Merges</title><description>&lt;p&gt;Well, I think that I have a solid foundation with the engine and syntax right now, I still have error conditions to verify, but that is something that I can handle as I go along. Now it is time to consider handling joins and merges. My initial thinking was something like:&lt;/p&gt; &lt;blockquote&gt;&lt;/blockquote&gt; &lt;blockquote&gt;&lt;pre&gt;&lt;font color="#0000ff"&gt;joinTransform&lt;/font&gt; UsersAndOrganizations:
	on: 
		Left.Id.ToString().Equals(Right.UserId)
	transform:
		Row.Copy(Left)
		Row.OrgId = Right["&lt;span style="color: #8b0000"&gt;Organization Id&lt;/span&gt;"]&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;The problem is that while this gives me equality operation, I can't handle sets very well, I have to compare each row vs. each row, and I would like to do it better. It would also mean having to do everything in memory, and I am not really crazy about that (nor particularly worried, will solved that when I need it).&lt;/p&gt;
&lt;p&gt;Another option is:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;font color="#0000ff"&gt;joinTransform&lt;/font&gt; UsersAndOrganizations:
	left:  [Row.Id, Row.UserName]
	right: [Row.UserId, Row.FullName]
	transform:
		Row.Copy(Left)
		Row.OrgId = Right["&lt;span style="color: #8b0000"&gt;Organization Id&lt;/span&gt;"]&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;This lets me handle it in a better way, since I now have two sets of keys, and I can do comparisons a lot more easily.That is a lot harder to read, though.&lt;/p&gt;
&lt;p&gt;Any suggestions?&lt;/p&gt;Both on the syntax and implementation strategies...</description><link>http://ayende.com/blog/2654/rhino-etl-thinking-about-joins-merges?key=fc5a5447-dfac-4540-9f56-b2e01c75352a</link><guid>http://ayende.com/blog/2654/rhino-etl-thinking-about-joins-merges?key=fc5a5447-dfac-4540-9f56-b2e01c75352a</guid><pubDate>Thu, 26 Jul 2007 19:54:03 GMT</pubDate></item><item><title>Rhino ETL: First Code Drop</title><description>&lt;p&gt;First, let me make it clear, it is not ready yet. &lt;/p&gt; &lt;p&gt;What we have:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;99% complete on the syntax  &lt;/li&gt;&lt;li&gt;Overall architecture should be stable  &lt;/li&gt;&lt;li&gt;The engine works - but I think of it as a spike, it is likely to change significantly.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;What remains to be done:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Parallelising the work inside a pipeline  &lt;/li&gt;&lt;li&gt;Better error messages  &lt;/li&gt;&lt;li&gt;More logging  &lt;/li&gt;&lt;li&gt;More tests  &lt;/li&gt;&lt;li&gt;Transforms over sets of rows&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Here are a few works about how it works. The DSL is compromised of connection, source, destination and transform, which has one to one mapping with the respective Connection, DataSource, DataDestination and Transform class. In some cases, we just fill the data in (Connection), in some cases we pass a generator (think of it as a delegate) to the instance that we create (DataSource, DataDestination), and sometimes we subclass the class to add the new behavior (transform).&lt;/p&gt; &lt;p&gt;A pipeline is a central concept, and is compromised of a set of pipeline associations, which connect the input/output of components.&lt;/p&gt; &lt;p&gt;Places to start looking at:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;EtlContextBuilder - Compile the DSL and spits out an instance of:  &lt;/li&gt;&lt;li&gt;EtlConfigurationContext - the result of the DSL, which can be run using:  &lt;/li&gt;&lt;li&gt;ExecutionPackage - the result of building the EtlConfigurationContext, this one manages the running of all the pipelines.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;There is an extensive set of tests (mostly for the syntax), and a couple of integration tests. As I said, anything that happens as a result of a call to ExecutionPackage.Execute() is suspect and will likely change. I may have been somewhat delegate happy in the execution, it is anonymous delegate that calls anonymous delegate, etc, which is probably too complex for what we need here.&lt;/p&gt; &lt;p&gt;I am putting the source out for review, while it can probably handle most simple things, it very bare bone and subject to change.&lt;/p&gt; &lt;p&gt;You can get it here: &lt;a title="https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/trunk/Rhino.ETL" href="https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/trunk/Rhino-ETL"&gt;https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/trunk/Rhino-ETL&lt;/a&gt;&lt;/p&gt; &lt;p&gt;But it needs references from the root, so it would be easiest to just do:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;svn checkout https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/trunk/Rhino.ETL&lt;/p&gt;&lt;/blockquote&gt;</description><link>http://ayende.com/blog/2651/rhino-etl-first-code-drop?key=0ac5ae6f-79ce-4aa4-a1ff-e5ff59749fce</link><guid>http://ayende.com/blog/2651/rhino-etl-first-code-drop?key=0ac5ae6f-79ce-4aa4-a1ff-e5ff59749fce</guid><pubDate>Mon, 23 Jul 2007 22:24:08 GMT</pubDate></item><item><title>Rhino.ETL: Full Package Syntax</title><description>&lt;p&gt;Okay, here is the full package syntax that I have now, which is enough to express quite a bit, I am now getting started on working on the engine itself, I am going to try the message passing architecture for now, since it is much more flexible.&lt;/p&gt; &lt;blockquote&gt;&lt;pre&gt;&lt;font color="#0000ff"&gt;connection&lt;/font&gt;( 
	"&lt;span style="color: #8b0000"&gt;NorthwindConnection&lt;/span&gt;",
	ConnectionType: SqlConnection,
	ConnectionString: "&lt;span style="color: #8b0000"&gt;Data Source=localhost;Initial Catalog=Northwind; Integrated Security=SSPI;&lt;/span&gt;"
	)

&lt;font color="#0000ff"&gt;source&lt;/font&gt; Northwind, Connection="&lt;span style="color: #8b0000"&gt;NorthwindConnection&lt;/span&gt;":
	Command: "&lt;span style="color: #8b0000"&gt;SELECT * FROM Orders WHERE RequiredDate BETWEEN @LastUpdate AND @CurrentDate&lt;/span&gt;"
	
	Parameters:
		@LastUpdate = date.Today.AddDays(-1)
		@CurrentTime = ExecuteScalar("&lt;span style="color: #8b0000"&gt;NorthwindConnection&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;SELECT MAX(RequiredDate) FROM Orders&lt;/span&gt;")

&lt;font color="#0000ff"&gt;transform&lt;/font&gt; ToLowerCase:
	&lt;span style="color: #0000ff"&gt;for&lt;/span&gt; column &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; Parameters.Columns:
		Row[column] = Row[column].ToLower() &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; Row[column] isa &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;

&lt;font color="#0000ff"&gt;destination&lt;/font&gt; Northwind, Connection = "&lt;span style="color: #8b0000"&gt;NorthwindConnection&lt;/span&gt;":
	Command: "&lt;span style="color: #8b0000"&gt;&lt;/span&gt;""
INSERT INTO [Orders_Copy]
(
	[CustomerID], [EmployeeID], [OrderDate], [RequiredDate], [ShippedDate],[ShipVia],
	[Freight],[ShipName],[ShipAddress],[ShipCity],[ShipRegion],[ShipPostalCode],
	[ShipCountry]
)
VALUES
(
	@CustomerID,@EmployeeID,@OrderDate,@RequiredDate,@ShippedDate,@ShipVia,@Freight,
	@ShipName,@ShipAddress,@ShipCity,@ShipRegion,@ShipPostalCode,@ShipCountry
)
"&lt;span style="color: #8b0000"&gt;&lt;/span&gt;""

&lt;font color="#0000ff"&gt;pipeline&lt;/font&gt; CopyOrders:
	Sources.Northwind &amp;gt;&amp;gt; ToLowerCase(Columns: ['ShipCity','ShipRegion'])
	ToLowerCase &amp;gt;&amp;gt; Destinations.Northwind &lt;/pre&gt;&lt;/blockquote&gt;</description><link>http://ayende.com/blog/2649/rhino-etl-full-package-syntax?key=e2e8d793-0f24-4a6a-8adf-eea1e3863a39</link><guid>http://ayende.com/blog/2649/rhino-etl-full-package-syntax?key=e2e8d793-0f24-4a6a-8adf-eea1e3863a39</guid><pubDate>Sat, 21 Jul 2007 16:10:23 GMT</pubDate></item><item><title>Rhino.ETL: Turning Transformations to FizzBuzz tests</title><description>&lt;p&gt;&lt;a href="http://www.tobinharris.com/blog"&gt;Tobin Harris&lt;/a&gt; has asked &lt;a href="http://ayende.com/Blog/archive/2007/07/20/9549.aspx#17258"&gt;some questions&lt;/a&gt; about how Rhino.ETL will handle transformations.  As you can see, I consider this something as trivial as a FizzBuzz test, which is a Good Thing, since it really should be so simple. Tobin's questions really show the current pain points in ETL processes.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Remove commas from numbers&lt;/li&gt;&lt;pre&gt;&lt;font color="#0000ff"&gt;transform&lt;/font&gt; RemoveCommas:
  &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; column &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; row.Columns:
	&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; row[column] isa &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;:
		row[column] = row[column].Replace("&lt;span style="color: #8b0000"&gt;,&lt;/span&gt;","&lt;span style="color: #8b0000"&gt;&lt;/span&gt;")&lt;/pre&gt;
&lt;li&gt;Trim and convert empty string to null&lt;/li&gt;&lt;pre&gt;&lt;font color="#0000ff"&gt;transform&lt;/font&gt; TrimEmptyStringToNull:
	&lt;span style="color: #0000ff"&gt;for&lt;/span&gt; column &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; row.Columns:
		val = row[column]
		&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; val isa &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;:
			row[column] = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; val.Trim().Length == 0&lt;/pre&gt;
&lt;li&gt;Reformat UK postcodes - No idea from what format, and to what format, but let us say that I have "SW1A0AA" and I want "SW1A 0AA"&lt;/li&gt;&lt;pre&gt;&lt;font color="#0000ff"&gt;transform&lt;/font&gt; IntroduceSpace:
	row.PostalCode = row.PostalCode.Substring(0,4) +' ' + row.PostalCode.Substring(4)&lt;/pre&gt;
&lt;li&gt;Make title case and Derive title from name and drop into column 'n':&lt;/li&gt;&lt;pre&gt;&lt;font color="#0000ff"&gt;transform&lt;/font&gt;  MakeTitleCase:
	row.Title = row.Name.Substring(0,1).ToUpper() + row.Name.Substring(1)&lt;/pre&gt;
&lt;li&gt;Remove blank rows - right now, you would need to check all the columns manually ( here is a sample for one column that should suffice in most cases ), if this is an important, it is easy to add the check in the row class itself, so you can ask for it directly.&lt;/li&gt;&lt;pre&gt;&lt;font color="#0000ff"&gt;transform&lt;/font&gt; RemoveRowsWithoutId:
	RemoveRow() &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; not row.Id&lt;/pre&gt;
&lt;li&gt;Format dates - I think you already got the idea, but never the less, let us take "Mar 04, 2007" and translate it to "2007-03-04", as an aside, it is probably easier to keep the date object directly.&lt;/li&gt;&lt;pre&gt;&lt;font color="#0000ff"&gt;transform&lt;/font&gt; TranslateDate:
	row.Date = date.Parse(row.Date).ToString("&lt;span style="color: #8b0000"&gt;yyyy-MM-dd&lt;/span&gt;")&lt;/pre&gt;
&lt;li&gt;Remove illegal dates&lt;/li&gt;&lt;pre&gt;&lt;font color="#0000ff"&gt;transform&lt;/font&gt; RemoveBadDate:
	tmp &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; date
	row.Date = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; not date.TryParse(row.Date, tmp)&lt;/pre&gt;&lt;/ul&gt;
&lt;p&gt;Things that I don't have an implementation of are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Remove repeated column headers in data - I don't understand the requirement.&lt;/li&gt;
&lt;li&gt;Unpivot repeated groups onto new rows, Unpivot( startCol, colsPerGroup, numberOfGroups) - I have two problems here, I never groked pivot/unpviot fully, so this require more research, but I have a more serious issue, and that is that this is a transformation over a &lt;em&gt;set of rows&lt;/em&gt;, and I can't thing of a good syntax for that, or the semantics it should have.&lt;br /&gt;I am opened for ideas...&lt;/li&gt;&lt;/ul&gt;</description><link>http://ayende.com/blog/2648/rhino-etl-turning-transformations-to-fizzbuzz-tests?key=aac66fcb-f592-43d0-a260-58b15a857639</link><guid>http://ayende.com/blog/2648/rhino-etl-turning-transformations-to-fizzbuzz-tests?key=aac66fcb-f592-43d0-a260-58b15a857639</guid><pubDate>Fri, 20 Jul 2007 23:12:56 GMT</pubDate></item><item><title>Rhino.ETL: Providing Answers</title><description>&lt;p&gt;It would be easier to me to answer a &lt;a href="http://ayende.com/Blog/archive/2007/07/20/9549.aspx#17255"&gt;few of the questions&lt;/a&gt; that has cropped up regarding Rhino.ETL.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Boo vs. Ruby&lt;/strong&gt;: Why I choose to go with Boo rather than Ruby. Very simple reasoning, my familiarity with Boo. I can make Boo do a lot of stuff already, I would have to start from scratch on Ruby. I don't see any value in one over the other, frankly, is there a reason behind the preference?&lt;/p&gt; &lt;p&gt;&lt;strong&gt;NAnt ETL Tasks: &lt;/strong&gt;The main problem I have with such an endeavor is that it is back to XML again, if I want to build complex processes, I want them to be easy to follow, and that exclude XML.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Active Warehouse&lt;/strong&gt;: Interesting idea, but that is using the imperative approach, I want to do something a little more declarative, and I really want it to be on the .Net platform (hence, much more familiar &amp;amp; debuggable). I also in a position where I believe that it would actually take me less time to build the tool than learn a tool in a new language.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Other OSS ETL tools:&lt;/strong&gt; There are quite a few OSS ETL tools that has been raised, they all share one problem from my perspective, they are not .Net and they are all visual / XML oriented. &lt;/p&gt; &lt;p&gt;I should also mention that I am building this project as preemptive step against the next project ETL's requirements, so I have both time to build it, and I have the craziest itch to scratch after dealing with SSIS in this project. The last time I was this excited about something, Rhino Mocks came out :-)&lt;/p&gt;</description><link>http://ayende.com/blog/2647/rhino-etl-providing-answers?key=a4e32be1-b0a1-4e55-8326-7061be8daa1b</link><guid>http://ayende.com/blog/2647/rhino-etl-providing-answers?key=a4e32be1-b0a1-4e55-8326-7061be8daa1b</guid><pubDate>Fri, 20 Jul 2007 22:22:55 GMT</pubDate></item><item><title>Framework building: Rhino.ETL Status Report</title><description>&lt;p&gt;I am currently working on making &lt;a href="http://www.ayende.com/Blog/archive/2007/07/19/Idea-The-Boo-ETL-DSL.aspx"&gt;this syntax&lt;/a&gt; possible, and letting ideas buzz at the back of my head regarding the implementation of the ETL engine itself. This probably requires some explanation. My idea about this is to separate the framework into two distinct layers. The core engine, which I'll talk about in a second, and the DSL syntax.&lt;/p&gt; &lt;p&gt;One of the basic design decisions was that the DSL would be declarative, and not imperative. How does this follow, when I have something like this working:&lt;/p&gt; &lt;blockquote&gt;&lt;pre&gt;&lt;font color="#0000ff"&gt;source&lt;/font&gt; ComplexGenerator:
	CommandGenerator:
		&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; Environment.GetEnvironmentVariable("&lt;span style="color: #8b0000"&gt;production&lt;/span&gt;"):
			&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; "&lt;span style="color: #8b0000"&gt;SELECT * FROM Production.Customers&lt;/span&gt;"
		&lt;span style="color: #0000ff"&gt;else&lt;/span&gt;:
			&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; "&lt;span style="color: #8b0000"&gt;SELECT * FROM Test.Customers&lt;/span&gt;"&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;This certainly looks like an imperative language to me... (And no, this isn't really an example of something that I would recommend doing, it is here just make the principal).&lt;/p&gt;
&lt;p&gt;The idea is that the DSL is used to build the object graph, then we can execute that object graph. But building it in a two stage fashion make it a lot easier to deal with such things as validation, visualization, etc.&lt;/p&gt;
&lt;p&gt;Now, let us more to the core engine, and see what I have been thinking about. Core concepts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Connection - The details about how to get the IDbConnection instance, including such things as number of concurrent connection, etc... 
&lt;/li&gt;&lt;li&gt;DataSource - Contains the details about how to get the data. Command to execute, parameters, associated connection, etc. 
&lt;/li&gt;&lt;li&gt;DataDestination - Contains the details about how to write the data, command / action to execute, parameters, connection, etc. 
&lt;/li&gt;&lt;li&gt;Row - A single row. A simple key &amp;lt;-&amp;gt; value structure with a twist that it can also contain other rows (from a merge/join) 
&lt;/li&gt;&lt;li&gt;Transform - Transform the current row 
&lt;/li&gt;&lt;li&gt;RowSet - a set of rows, obviously, useful for aggregation, lookup, etc. Not really sure how it should come into play yet.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;The architecture of the whole thing is based on the pipeline idea, obviously. Now, there are several implementation decisions that should be considered from there.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Destination as the driver. &lt;/strong&gt;The destination is the driver behind this architecture, it request the next row from the pipeline, which starts things rolling. Implementation can be as simple as:&lt;pre&gt;&lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt;(Row row &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; Pipeline.NextRow())
{
	PushToDestination(row);
} &lt;/pre&gt;This has the side affect of making the entire pipeline single threaded per destination, it makes it much easier to implement, and would make it easier to see the flow of things. Parallelism can be managed by multiple pipelines and/or helper threads. The major benefit in parallelism is with the data read/write, and those are limited to a pipeline at any rate.&lt;br /&gt;It does bring up the interesting question of how to deal with something like merge join, which requires multiply inputs, you would need to manage the different inputs in the merge, but I think that this is mandatory anyway.&lt;/li&gt;&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Message passing architecture&lt;/strong&gt;. In this architecture, each component (source, transform, destination) is basically an independent object with input/output channels, they all operate without reliance on each other. This is more complex because you can't do the simplest thing of just giving each component a thread, so you need to manage yielding and concurrency to a much higher degree.&lt;br /&gt;A bigger issue is that it puts a higher burden on writing components.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Right now I am leaning toward going to the single threaded pipeline idea, any comments?&lt;/p&gt;</description><link>http://ayende.com/blog/2646/framework-building-rhino-etl-status-report?key=841ab792-7b54-49aa-923b-2278e571bcc2</link><guid>http://ayende.com/blog/2646/framework-building-rhino-etl-status-report?key=841ab792-7b54-49aa-923b-2278e571bcc2</guid><pubDate>Fri, 20 Jul 2007 21:17:00 GMT</pubDate></item><item><title>Test driving Rhino.ETL</title><description>&lt;p&gt;Here is the first test: &lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;[Test] 
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; EvaluatingScript_WithConnection_WillAddDataSourceToContext() 
{ 
	EtlConfigurationContext configurationContext = EtlContextBuilder.FromFile(@"&lt;span style="color: #8b0000"&gt;Connections\connection_only.retl&lt;/span&gt;");
	Assert.AreEqual(3, configurationContext.Connections.Count, "&lt;span style="color: #8b0000"&gt;should have three connections&lt;/span&gt;");
}&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;There is quite a bit of information just in this test, we introduced the EtlConfigurationContext class, decided that we will create it from a factory, and that we have something that is called a connection. Another decision made was the “retl” extension (Rhino ETL), but that is a side benefit.
&lt;/p&gt;&lt;p&gt;The source for this is:
&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;Connection( 
	"&lt;span style="color: #8b0000"&gt;Northwind&lt;/span&gt;",
	ConnectionType: SqlConnection,
	ConnectionString: "&lt;span style="color: #8b0000"&gt;Data Source=localhost;Initial Catalog=Northwind; Integrated Security=SSPI;&lt;/span&gt;",
	ConcurrentConnections: 5
	)
	
Connection( 
	"&lt;span style="color: #8b0000"&gt;SouthSand&lt;/span&gt;",
	ConnectionType: OracleConnection,
	ConnectionStringName: "&lt;span style="color: #8b0000"&gt;SouthSand&lt;/span&gt;"
	)

Connection( 
	"&lt;span style="color: #8b0000"&gt;StrangeOne&lt;/span&gt;",
	ConnectionType: OracleConnection,
	ConnectionStringGenerator: { System.Environment.GetEnvironmentVariable("&lt;span style="color: #8b0000"&gt;MyEnvVar&lt;/span&gt;") }
	)&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;You may have wondered about the last one, what does this do? Well, it allows you to do runtime evaluation of something, in this case, it get the value from an env-var, but that has a lot of potential. Here it a test that demonstrate the capabilities:
&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;[Test]
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; DataSources_ConnectionStringGenerator_CanUseEvnrionmentVariables()
{
	Environment.SetEnvironmentVariable("&lt;span style="color: #8b0000"&gt;MyEnvVar&lt;/span&gt;","&lt;span style="color: #8b0000"&gt;MyExpectedValue&lt;/span&gt;");

	Assert.AreEqual(
			"&lt;span style="color: #8b0000"&gt;MyExpectedValue&lt;/span&gt;",
			configurationContext.Connections["&lt;span style="color: #8b0000"&gt;StrangeOne&lt;/span&gt;"].ConnectionString
	);

	Environment.SetEnvironmentVariable("&lt;span style="color: #8b0000"&gt;MyEnvVar&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;2&lt;/span&gt;");

	Assert.AreEqual(
			"&lt;span style="color: #8b0000"&gt;2&lt;/span&gt;",
			configurationContext.Connections["&lt;span style="color: #8b0000"&gt;StrangeOne&lt;/span&gt;"].ConnectionString
	);

}
&lt;/pre&gt;&lt;/blockquote&gt;</description><link>http://ayende.com/blog/2645/test-driving-rhino-etl?key=207da555-c86a-4511-b236-7b897b9e8708</link><guid>http://ayende.com/blog/2645/test-driving-rhino-etl?key=207da555-c86a-4511-b236-7b897b9e8708</guid><pubDate>Thu, 19 Jul 2007 22:33:03 GMT</pubDate></item><item><title>Dependency Injection in Web Forms MVC</title><description>&lt;p&gt;&lt;a href="http://codebetter.com/blogs/david.hayden/"&gt;David Hayden&lt;/a&gt; has a post about the issue that you face when you are trying to use &lt;a href="http://codebetter.com/blogs/david.hayden/archive/2007/06/27/dependency-injection-and-mvp-in-webforms-it-s-that-injection-of-the-presenter-into-the-view-that-stinks.aspx"&gt;dependency injection in Web Forms MVC&lt;/a&gt;. I talked about similar issues &lt;a href="http://www.ayende.com/Blog/archive/2007/06/01/MVC-in-WebForms-The-impossible-fight-to-get-rid-of.aspx"&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;He points out that this type of code is bad:&lt;/p&gt;&lt;pre&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; Page_PreInit(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, EventArgs e)
    {
            &lt;span style="color: #008000"&gt;// Constructor Injection of Data Access Service and View&lt;/span&gt;
            ICustomerDAO dao = Container.Resolve&amp;lt;ICustomerDAO&amp;gt;():
            _presenter = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; AddCustomerPresenter(dao, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;);
            
            &lt;span style="color: #008000"&gt;// Property Injection of Logging&lt;/span&gt;
            ILoggingService logger = Container.Resolve&amp;lt;ILoggingService&amp;gt;():
            _presenter.Logger = logger;
    }&lt;/pre&gt;
&lt;p&gt;This type of code a Worst Practice in my opinion. It means that the &lt;strong&gt;view&lt;/strong&gt; is responsible for setting up the presenter, that is a &lt;em&gt;big&lt;/em&gt; No! right there.&lt;/p&gt;
&lt;p&gt;He gives the example of WCSF &amp;amp; Object Builder way of doing it, but I don't think that this is a good approach:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;font color="#0000ff"&gt;partial&lt;/font&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; AddCustomer : Page, IAddCustomer
{
    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; AddCustomerPresenter _presenter;

    [CreateNew]
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; AddCustomerPresenter Presenter
    {
        &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;
        {
            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._presenter = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;
            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._presenter.View = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;;
        }
    }
    
    &lt;span style="color: #008000"&gt;// ...&lt;/span&gt;
}&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;The problems that I have with this approach is that the view suddenly makes assumptions about the life cycle of the controller, which is not something that I want it to do. I may want a controller per conversation, for instance, and then where would I be? Another issue is that the view is responsible for injecting itself to presenter, which is not something that I would like to see there as well.&lt;/p&gt;
&lt;p&gt;Here is how I do it with Rhino.Igloo:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;font color="#0000ff"&gt;partial&lt;/font&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; AddCustomer : BasePage, IAddCustomer
{
    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; AddCustomerPresenter _presenter;

    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; AddCustomerPresenter Presenter
    {
        &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;
        {
            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._presenter = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;
        }
    }
    
    &lt;span style="color: #008000"&gt;// ...&lt;/span&gt;
}&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;The &lt;a href="http://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/trunk/rhino-igloo/Rhino.Igloo/IoC/BijectionFacility.cs"&gt;BijectionFacility&lt;/a&gt; will notice that we have a settable property of type that inherit from BaseController, and will get it from the container and inject that in. I don't believe in explicit Controller-&amp;gt;View communication, but assuming that I needed that, it would be &lt;em&gt;very &lt;/em&gt;easy to inject that into the presenter. Very easy as in adding three lines of code to &lt;a href="https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/trunk/rhino-igloo/Rhino.Igloo/Web/ComponentRepository.cs"&gt;ComponentRepository&lt;/a&gt;'s InjectControllers method:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;PropertyInfo view = controller.GetType().GetProperty("&lt;span style="color: #8b0000"&gt;View&lt;/span&gt;");
&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(view!=&lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
	view.SetValue(controller, instance);&lt;/pre&gt;&lt;/blockquote&gt;</description><link>http://ayende.com/blog/2605/dependency-injection-in-web-forms-mvc?key=60d4bf82-c9a1-4aa9-ae9c-e15e8f03534f</link><guid>http://ayende.com/blog/2605/dependency-injection-in-web-forms-mvc?key=60d4bf82-c9a1-4aa9-ae9c-e15e8f03534f</guid><pubDate>Wed, 27 Jun 2007 22:40:04 GMT</pubDate></item><item><title>Rhino Commons, Repository&lt;T&gt; and Unit Of Work</title><description>&lt;p&gt;Rhino Commons is a great collection of stuff that I gathered along the way, but never documented. There is a sample application (https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/trunk/SampleApplications/Exesto), but not much more.  I want to spend a few minutes talking about the way the data access part of it works. This is post about how it works, not how to make it work (in other words, very little code here).&lt;/p&gt; &lt;p&gt;Before I start, I want to mentions that Rhino Commons is (highly) opinionated software, unlike Castle or NHibernate. It is a separate place where I take what Castle &amp;amp; NHibernate gives me, add a mix of my own best practices and let it run.&lt;/p&gt; &lt;p&gt;The data access part in Rhino Commons revolves around the Unit Of Work, Unit Of Work Factory and the Unit Of Work Application. The main abstraction that Rhino Commons provides in terms on data access is the IRepository&amp;lt;T&amp;gt; interface, which is accessible via the static Repository&amp;lt;T&amp;gt; accessor class. The Unit Of Work class and the IRepository&amp;lt;T&amp;gt; works together to simplify data access code in most cases.&lt;/p&gt; &lt;p&gt;It started as a set of wrapper methods and sort of grew from there. I find that this is very useful for intent revealing code when used in conjunction with the NHibernate Query Generator. Another useful tidbit is that it also serve to handle the differences between NHibernate &amp;amp; Active Record models fairly transparently this allows me to work against the NHibernate model (me likey) without having to define any XML (me likey more!) :-)&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/RhinoCommonsRepositoryTUnitOfWork_ECA/image_1.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="309" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/RhinoCommonsRepositoryTUnitOfWork_ECA/image_thumb_1.png" width="283" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;As you can see, the IRepository&amp;lt;T&amp;gt; is serving as a way to query NHibernate very easily. In a DDD environment I'll probably inherit from it and add additional methods to it, like CustomersThatTheUserIsAllowedToView(User user), etc.&lt;/p&gt; &lt;p&gt;Another thing that the use of the Repository gives me is the ability to do cross cutting concerns with queries, things like With.Caching, With.Transaction (although I prefer the Automatic Transaction Management Facility more), etc. It is &lt;strong&gt;important&lt;/strong&gt; to note that the default Flush Mode for the session using this approach is Commit only, so Transactions play an important role here.&lt;/p&gt; &lt;p&gt;After the IRepository&amp;lt;T&amp;gt;, we have the Unit Or Work itself, which is basically responsible to manage the NHibernate session / Active Record Scope. Unit Of Work Factory is used to initialize NHibernate / Active Record and to create new Units Of Work.&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/RhinoCommonsRepositoryTUnitOfWork_ECA/image_2.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="199" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/RhinoCommonsRepositoryTUnitOfWork_ECA/image_thumb_2.png" width="451" border="0" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Note that while you can create Unit Of Work using the IUnitOfWorkFactory, you query it using the Repository. The idea is that most of the time, you are only dealing with the Repository, and dealing with the Unit Of Work is left to a higher level code. I am a big believer in context being king, and this is one case of many where I am using this approach.&lt;/p&gt; &lt;p&gt;If the management of the Unit Of Work is relegated to a higher level code, who is responsible for managing it?&lt;/p&gt; &lt;p&gt;That is the job of the UnitOfWorkApplication, which handles the session per request pattern. This is an HttpApplication rather than the usual Http Module since HttpApplication.Application_start is guaranteed to run once and only once, while Http Modules can be created/disposed based on load.&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/RhinoCommonsRepositoryTUnitOfWork_ECA/image.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="314" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/RhinoCommonsRepositoryTUnitOfWork_ECA/image_thumb.png" width="283" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Notice that the UnitOfWorkApplication is also responsible to create the container, after which it is available to the rest of the application.&lt;/p&gt;</description><link>http://ayende.com/blog/2527/rhino-commons-repository-t-and-unit-of-work?key=a2c59755-02f8-4d53-a794-0856423cb97e</link><guid>http://ayende.com/blog/2527/rhino-commons-repository-t-and-unit-of-work?key=a2c59755-02f8-4d53-a794-0856423cb97e</guid><pubDate>Thu, 07 Jun 2007 22:59:07 GMT</pubDate></item></channel></rss>