<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>NHibernate blog</title><link>http://nhforge.org/blogs/nhibernate/default.aspx</link><description /><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/NHibernateBlog" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><title>NHibernate and WPF: The GuyWire</title><link>http://feedproxy.google.com/~r/NHibernateBlog/~3/0xtoLZmcBdM/nhibernate-and-wpf-the-guywire.aspx</link><pubDate>Sat, 07 Nov 2009 19:12:52 GMT</pubDate><guid isPermaLink="false">45f813f2-f1c4-4eda-a619-288e3cadc793:539</guid><dc:creator>Jose Romaniello</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://nhforge.org/blogs/nhibernate/rsscomments.aspx?PostID=539</wfw:commentRss><comments>http://nhforge.org/blogs/nhibernate/archive/2009/11/07/nhibernate-and-wpf-the-guywire.aspx#comments</comments><description>&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note: I owe this knowledge to my friend &lt;a href="http://fabiomaulo.blogspot.com/"&gt;Fabio Maulo&lt;/a&gt;, so I would like to thank him for teaching me and letting me share.&lt;/em&gt;&lt;/strong&gt; &lt;/p&gt;  &lt;h1&gt;Introduction&lt;/h1&gt;  &lt;p&gt;I will show you in this post a nice way to configure your IoC container and some other aspects of your applications. I assume for this article that you have good knowledge of dependency injection and inversion of control.&lt;/p&gt;  &lt;h1&gt;The problem&lt;/h1&gt;  &lt;p&gt;There was a time when we used to configure our containers with xml, and all was fine. Then we started to use fluent and strongly typed interfaces and a problem became more frequent and acute. Basically, when we use a fluent interface, we do something like this:&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;container.Register(Component.For&amp;lt;IAlbumRepository&amp;gt;()
                       .ImplementedBy&amp;lt;AlbumRepository&amp;gt;()
                       .LifeStyle.Transient);&lt;/pre&gt;

&lt;p&gt;IAlbumRepository is in Chinook.Data and AlbumRepository is in Chinook.Data.Impl.&amp;#160; &lt;br /&gt;The problem is not *how* but &lt;strong&gt;&lt;u&gt;*where*&lt;/u&gt;&lt;/strong&gt;. Where do you do this? &lt;/p&gt;

&lt;p&gt;Most people will say “The startup project”. One of the goal that we look when using IoC is:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;..decoupling of the execution of a certain task from implementation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pay attention to the “Decoupling” part. If you want “decoupling”: Why do you add all those references in your startup project?&lt;/p&gt;

&lt;p&gt;This is a &lt;a href="http://www.ndepend.com/"&gt;NDepend&lt;/a&gt; extracted graph of the Northwind example that comes with &lt;a href="http://www.sharparchitecture.net/"&gt;Sharp Architecture&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img border="0" src="http://content.screencast.com/users/JoseFR/folders/Jing/media/82a585f2-6ae5-4f3b-ba29-fc3f283be6ad/2009-10-26_1333.png" width="585" height="336" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;If you look at the Northwind.Web assembly you will see that it has a reference even to NHibernate. It has a reference to Northwind.Data (repositories that use NHibernate). The contract interface of repositories is in Northwind.Core. Also you can see that the start up project need a reference to Castle Container. If I want a loosely coupled solution, I don’t want some of those references.&lt;/p&gt;

&lt;p&gt;Pay atention; the northwind example of Sharp Architecture is a very good example, is a good architecture, and this is neither a complain nor a criticism. I’m pretty sure that it defines interfaces and implementations separately, as I’m pretty sure that controllers depends upon IRepositories. But, I think it has a problem at reference level. The main problem is because the initialization of the container is in a wrong place. You could see the initialization script &lt;a href="http://github.com/codai/Sharp-Architecture/blob/master/src/NorthwindSample/app/Northwind.Web/CastleWindsor/ComponentRegistrar.cs"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, what I’m looking for is:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;I don’t want references to concrete implementations in my startup project. &lt;/li&gt;

  &lt;li&gt;I don’t want to depend upon a specific IoC container technology. &lt;/li&gt;

  &lt;li&gt;And finally I don’t want to configure my container in the startup project, its is another “aspect” of my application like the repositories! &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;/p&gt;

&lt;h1&gt;The Solution&lt;/h1&gt;

&lt;p&gt;The solution is very simple. Take the container initialization to another place. &lt;/p&gt;

&lt;p&gt;We used to call this place “The GuyWire”, in italian “Cavo Portante”, in spanish “Cable Maestro”:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;A &lt;b&gt;guy-wire&lt;/b&gt; or &lt;b&gt;guy-rope&lt;/b&gt; is a tensioned cable designed to add stability to structures&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Two simple rules to remember:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;In order to configure service and implementers fluently, the GuyWire will reference everything. &lt;/li&gt;

  &lt;li&gt;Because the guy-wire reference everything, the GuyWire can not be referenced. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The guywire is an excellent place to “configure” the whole application. I used to separate the configuration in different aspects. Here some examples:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ORM configuration &lt;/li&gt;

  &lt;li&gt;Constraint Validator configuration &lt;/li&gt;

  &lt;li&gt;Repositories configuration &lt;/li&gt;

  &lt;li&gt;Entities configuration &lt;/li&gt;

  &lt;li&gt;ViewModel configuration &lt;/li&gt;

  &lt;li&gt;Controllers configuration &lt;/li&gt;

  &lt;li&gt;Views configuration &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can explore the configurators of ChinookMediaManager &lt;a href="http://code.google.com/p/unhaddins/source/browse/#svn/trunk/Examples/uNHAddIns.Examples.WPF/ChinookMediaManager.GuyWire/Configurators"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;How does it works?&lt;/h2&gt;

&lt;p&gt;The guywire project has an special “Output Path”:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://nhforge.org/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/nhibernate/image_5F00_53062B8B.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://nhforge.org/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/nhibernate/image_5F00_thumb_5F00_6AC28453.png" width="552" height="255" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;So, the path is the “Startup” project.&lt;/p&gt;

&lt;p&gt;Secondly, in the App.Config, I have a config like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;appSettings&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;add &lt;/span&gt;&lt;span style="color:red;"&gt;key&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;GuyWire&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;value&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;ChinookMediaManager.GuyWire.GeneralGuyWire, ChinookMediaManager.GuyWire&lt;/span&gt;&amp;quot; &lt;span style="color:blue;"&gt;/&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;appSettings&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;And finally, in my App.Xaml.cs:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public partial class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;App &lt;/span&gt;: Application
{
    &lt;span style="color:blue;"&gt;private readonly &lt;/span&gt;IGuyWire guyWire = ApplicationConfiguration.GetGuyWire();

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;App()
    {
        guyWire.Wire();
    }

    &lt;span style="color:blue;"&gt;protected override void &lt;/span&gt;OnStartup(StartupEventArgs e)
    {
        &lt;span style="color:blue;"&gt;var &lt;/span&gt;viewFactory = ServiceLocator.Current.GetInstance&amp;lt;IViewFactory&amp;gt;();
        viewFactory.ShowView&amp;lt;BrowseArtistViewModel&amp;gt;();
    }

    &lt;span style="color:blue;"&gt;protected override void &lt;/span&gt;OnExit(ExitEventArgs e)
    {
        guyWire.Dewire();
        &lt;span style="color:blue;"&gt;base&lt;/span&gt;.OnExit(e);
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The interface IGuyWire and other classes needed for doing this, are in unhaddins.&lt;/p&gt;

&lt;p&gt;The reference graph of the Chinook Media Manager, is as follows:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://nhforge.org/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/nhibernate/image_5F00_4961041A.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://nhforge.org/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/nhibernate/image_5F00_thumb_5F00_4FAA6B59.png" width="578" height="593" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;A last word about the Configurators&lt;/h2&gt;

&lt;p&gt;I really like the idea of have different parts of the application configuration in separated classes. I used to reuse this configurators alone in my Tests. But, as a I said before, the guywire should not be referenced by any project. So, my trick is add the configurator as a “linked file” to the test project:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://nhforge.org/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/nhibernate/image_5F00_6BBD04E1.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://nhforge.org/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/nhibernate/image_5F00_thumb_5F00_400C3AE5.png" width="243" height="117" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;And this is a sample:&lt;/p&gt;

&lt;pre class="code"&gt;[&lt;span style="color:#2b91af;"&gt;TestFixture&lt;/span&gt;]
&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;AlbumValidationFixture
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IWindsorContainer &lt;/span&gt;container;

    [&lt;span style="color:#2b91af;"&gt;TestFixtureSetUp&lt;/span&gt;]
    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;FixtureSetUp()
    {
        container = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;WindsorContainer&lt;/span&gt;();
        &lt;span style="color:blue;"&gt;var &lt;/span&gt;configurator = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;NHVConfigurator&lt;/span&gt;();
        configurator.Configure(container);
    }

    [&lt;span style="color:#2b91af;"&gt;Test&lt;/span&gt;]
    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;title_constraints()
    {
        GetConstraint&amp;lt;&lt;span style="color:#2b91af;"&gt;Album&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;NotEmptyAttribute&lt;/span&gt;&amp;gt;(a =&amp;gt; a.Title)
            .Message
            .Should().Be.EqualTo(&lt;span style="color:#a31515;"&gt;&amp;quot;Title should not be null.&amp;quot;&lt;/span&gt;);

        GetConstraint&amp;lt;&lt;span style="color:#2b91af;"&gt;Album&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;LengthAttribute&lt;/span&gt;&amp;gt;(a =&amp;gt; a.Title)
            .Should().Be.OfType&amp;lt;&lt;span style="color:#2b91af;"&gt;LengthAttribute&lt;/span&gt;&amp;gt;()
            .And.ValueOf.Message.Should().Be.EqualTo(&lt;span style="color:#a31515;"&gt;&amp;quot;Title should not exceed 200 chars.&amp;quot;&lt;/span&gt;);
            
        
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;I will not talk about this long break in the series. If you are interested in Wpf and Nhibernate, you should be happy because; &lt;strong&gt;&lt;u&gt;I&amp;#39;M BACK&lt;/u&gt;!&lt;/strong&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://nhforge.org/aggbug.aspx?PostID=539" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Tr4vn7UUsLJPCbVse0t4muPFVO8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Tr4vn7UUsLJPCbVse0t4muPFVO8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Tr4vn7UUsLJPCbVse0t4muPFVO8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Tr4vn7UUsLJPCbVse0t4muPFVO8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/NHibernateBlog/~4/0xtoLZmcBdM" height="1" width="1"/&gt;</description><category domain="http://nhforge.org/blogs/nhibernate/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://nhforge.org/blogs/nhibernate/archive/tags/WPF/default.aspx">WPF</category><feedburner:origLink>http://nhforge.org/blogs/nhibernate/archive/2009/11/07/nhibernate-and-wpf-the-guywire.aspx</feedburner:origLink></item><item><title>NHibernate Validator 1.2 Beta3 released</title><link>http://feedproxy.google.com/~r/NHibernateBlog/~3/TguI2GnZnUc/nhibernate-validator-1-2-beta3-released.aspx</link><pubDate>Mon, 26 Oct 2009 16:12:00 GMT</pubDate><guid isPermaLink="false">45f813f2-f1c4-4eda-a619-288e3cadc793:534</guid><dc:creator>Dario Quintana</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://nhforge.org/blogs/nhibernate/rsscomments.aspx?PostID=534</wfw:commentRss><comments>http://nhforge.org/blogs/nhibernate/archive/2009/10/26/nhibernate-validator-1-2-beta3-released.aspx#comments</comments><description>&lt;p&gt;&lt;img src="http://darioquintana.com.ar/files/NHV-logo-white-background.png" alt="" /&gt;

&lt;/p&gt;
&lt;p&gt;Download NHibernate Validator 1.2 beta3 with sources, binaries and example here &lt;a href="https://sourceforge.net/projects/nhcontrib/files"&gt;here&lt;/a&gt;

&lt;/p&gt;
&lt;p&gt;For use it with NHibernate 2.1 GA.
&lt;/p&gt;
&lt;p&gt;For examples and documentation see the serie of blog posts of Fabio Maulo about NHibernate Validator &lt;a href="http://fabiomaulo.blogspot.com/search/label/Validator"&gt;here&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://nhforge.org/aggbug.aspx?PostID=534" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/LIU7SNMXoGD9ClEDgF6xqTqUxRY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LIU7SNMXoGD9ClEDgF6xqTqUxRY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/LIU7SNMXoGD9ClEDgF6xqTqUxRY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LIU7SNMXoGD9ClEDgF6xqTqUxRY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/NHibernateBlog/~4/TguI2GnZnUc" height="1" width="1"/&gt;</description><category domain="http://nhforge.org/blogs/nhibernate/archive/tags/validation/default.aspx">validation</category><category domain="http://nhforge.org/blogs/nhibernate/archive/tags/News/default.aspx">News</category><category domain="http://nhforge.org/blogs/nhibernate/archive/tags/Release/default.aspx">Release</category><category domain="http://nhforge.org/blogs/nhibernate/archive/tags/Validator/default.aspx">Validator</category><feedburner:origLink>http://nhforge.org/blogs/nhibernate/archive/2009/10/26/nhibernate-validator-1-2-beta3-released.aspx</feedburner:origLink></item><item><title>hbm2net </title><link>http://feedproxy.google.com/~r/NHibernateBlog/~3/6aYI97d6S84/hbm2net.aspx</link><pubDate>Mon, 19 Oct 2009 07:43:00 GMT</pubDate><guid isPermaLink="false">45f813f2-f1c4-4eda-a619-288e3cadc793:526</guid><dc:creator>felicepollano</dc:creator><slash:comments>5</slash:comments><wfw:commentRss>http://nhforge.org/blogs/nhibernate/rsscomments.aspx?PostID=526</wfw:commentRss><comments>http://nhforge.org/blogs/nhibernate/archive/2009/10/19/hbm2net.aspx#comments</comments><description>&lt;p&gt;I did an attempt of resuming the project hbm2net, creating a &lt;a href="http://msdn.microsoft.com/en-us/library/bb126445.aspx" target="_blank"&gt;Text Template Transformation Toolkit (T4)&lt;/a&gt;&amp;nbsp; renderer, hosting the T4 engine. T4 templates allow to easily mix templates with additional code.The current version is not production code, but a proof-of-concept. If anyone interested a &lt;a href="http://cid-b8821720666a55e7.skydrive.live.com/self.aspx/.Public/NHibernate.Tool.hbm2net.zip"&gt;download&lt;/a&gt; is provided, containing the source and a single unit test to show the idea. A ready to use binary version could be found &lt;a href="http://www.felicepollano.com/post/hbm2net-tentativo-di-resurrezione.aspx"&gt;here&lt;/a&gt; (post is in italian, but is easy to grasp how to try it),as I said, it is not tested for production. Please let me know if the idea is useful / interesting.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://nhforge.org/aggbug.aspx?PostID=526" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/hW0ScqvssaYgxaAK3IL65AC7Mqc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hW0ScqvssaYgxaAK3IL65AC7Mqc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/hW0ScqvssaYgxaAK3IL65AC7Mqc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hW0ScqvssaYgxaAK3IL65AC7Mqc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/NHibernateBlog/~4/6aYI97d6S84" height="1" width="1"/&gt;</description><category domain="http://nhforge.org/blogs/nhibernate/archive/tags/hbm2net/default.aspx">hbm2net</category><feedburner:origLink>http://nhforge.org/blogs/nhibernate/archive/2009/10/19/hbm2net.aspx</feedburner:origLink></item><item><title>Mapping different types - IUserType</title><link>http://feedproxy.google.com/~r/NHibernateBlog/~3/IEE_MsXdGEE/mapping-different-types-iusertype.aspx</link><pubDate>Thu, 15 Oct 2009 18:21:00 GMT</pubDate><guid isPermaLink="false">45f813f2-f1c4-4eda-a619-288e3cadc793:525</guid><dc:creator>Krzysztof Kozmic</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://nhforge.org/blogs/nhibernate/rsscomments.aspx?PostID=525</wfw:commentRss><comments>http://nhforge.org/blogs/nhibernate/archive/2009/10/15/mapping-different-types-iusertype.aspx#comments</comments><description>&lt;p&gt;Recently I had a problem with the application I&amp;rsquo;ve been working on. One of entity types in my domain had a property of type &lt;i&gt;uint&lt;/i&gt;. Not a big deal, until you want to store it in Microsoft SQL Server database which &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/ms187752.aspx"&gt;does not support unsigned types&lt;/a&gt;. I&amp;rsquo;ve been scratching my head for a moment and then I found a solution &amp;ndash; let&amp;rsquo;s map it as &lt;i&gt;long&lt;/i&gt; in our database. Since &lt;i&gt;long&lt;/i&gt; can represent any legal value of &lt;i&gt;uint&lt;/i&gt;, we should be all good, right? So let&amp;rsquo;s do it.&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;div class="csharpcode"&gt;
&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ClassWithUintProperty&lt;/pre&gt;
&lt;pre&gt;{&lt;/pre&gt;
&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; Guid Id { get; set; }&lt;/pre&gt;
&lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;uint&lt;/span&gt; UintProp { get ;set; }&lt;/pre&gt;
&lt;pre class="alt"&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="html"&gt;xml&lt;/span&gt; &lt;span class="attr"&gt;version&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt;?&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;hibernate-mapping&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;urn:nhibernate-mapping-2.2&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;                   &lt;span class="attr"&gt;assembly&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;NHibernate.Test&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;                   &lt;span class="attr"&gt;namespace&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;NHibernate.Test&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;class&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;ClassWithUintProperty&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;id&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Id&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UIntProp&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;not-null&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;long&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;class&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;hibernate-mapping&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3&gt;&amp;quot;Houston, we&amp;#39;ve had a problem&amp;quot;&lt;/h3&gt;
&lt;p&gt;All good. At least until you try to fetch saved value from the database. When you do, you&amp;rsquo;re up for an unpleasant surprise:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;System.InvalidCastException: Specified cast is not valid.&lt;/p&gt;
&lt;p&gt;NHibernate.PropertyAccessException: Invalid Cast (check your mapping for property type mismatches); setter of NHibernate.Test.UIntAsLong&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The exception is a result of how NHibernate optimizes property access and quirks of mixing different conversion operators (unboxing and numeric conversion in this case) and are not really interesting. What&amp;rsquo;s important, is that we approached the problem from the wrong angle.&lt;/p&gt;
&lt;p&gt;What we&amp;rsquo;re dealing with here, is inability of our database engine to deal with datatype in our model, which we were trying to solve by pushing this onto NHibernate without telling it something is &amp;lsquo;&amp;rdquo;wrong&amp;rdquo;. While NHibernate is smart, it&amp;rsquo;s working based on a set of explicit information, so what we need to do, is to be explicit about what we want it to do.&lt;/p&gt;
&lt;p&gt;There are two places where we can tell NHibernate about it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IUserType, which will explicitly handle the mapping from &lt;i&gt;uint&lt;/i&gt; in our model to &lt;i&gt;long&lt;/i&gt; in the DB &lt;/li&gt;
&lt;li&gt;custom Dialect which will basically lie to NHibernate telling it &amp;ldquo;yeah, sure this DB supports &lt;i&gt;uint&lt;/i&gt;s &amp;ndash; whole dozens of &amp;lsquo;em!&amp;rdquo; and do some work under the covers to live up to its promise. (not shown in this post). &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Enter IUserType&lt;/h3&gt;
&lt;p&gt;&lt;a target="_blank" href="http://nhforge.org/doc/nh/en/index.html#mapping-types-custom"&gt;IUserType&lt;/a&gt; is an extension point in NHibernate that let&amp;rsquo;s you plug in to the mapping process and handle it yourself. The interface is quite big, but there&amp;rsquo;s very little real logic there:&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; UIntAsLong:IUserType&lt;/pre&gt;
&lt;pre&gt;{&lt;/pre&gt;
&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; SqlType[] SqlTypes&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class="alt"&gt;            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt;[] { SqlTypeFactory.Int64 }; }&lt;/pre&gt;
&lt;pre&gt;        }&lt;/pre&gt;
&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Type ReturnedType&lt;/pre&gt;
&lt;pre class="alt"&gt;        {&lt;/pre&gt;
&lt;pre&gt;            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;typeof&lt;/span&gt;( &lt;span class="kwrd"&gt;uint&lt;/span&gt; ); }&lt;/pre&gt;
&lt;pre class="alt"&gt;        }&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; IsMutable&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class="alt"&gt;            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;; }&lt;/pre&gt;
&lt;pre&gt;        }&lt;/pre&gt;
&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; GetHashCode( &lt;span class="kwrd"&gt;object&lt;/span&gt; x )&lt;/pre&gt;
&lt;pre class="alt"&gt;        {&lt;/pre&gt;
&lt;pre&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt;( x == &lt;span class="kwrd"&gt;null&lt;/span&gt; )&lt;/pre&gt;
&lt;pre class="alt"&gt;            {&lt;/pre&gt;
&lt;pre&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; 0;&lt;/pre&gt;
&lt;pre class="alt"&gt;            }&lt;/pre&gt;
&lt;pre&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; x.GetHashCode();&lt;/pre&gt;
&lt;pre class="alt"&gt;        }&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; NullSafeGet( IDataReader rs, &lt;span class="kwrd"&gt;string&lt;/span&gt;[] names, &lt;span class="kwrd"&gt;object&lt;/span&gt; owner )&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;object&lt;/span&gt; obj = NHibernateUtil.UInt32.NullSafeGet( rs, names0 );&lt;/pre&gt;
&lt;pre&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt;( obj == &lt;span class="kwrd"&gt;null&lt;/span&gt; )&lt;/pre&gt;
&lt;pre class="alt"&gt;            {&lt;/pre&gt;
&lt;pre&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;/pre&gt;
&lt;pre class="alt"&gt;            }&lt;/pre&gt;
&lt;pre&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; (&lt;span class="kwrd"&gt;uint&lt;/span&gt;)obj;&lt;/pre&gt;
&lt;pre class="alt"&gt;        }&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; NullSafeSet( IDbCommand cmd, &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;, &lt;span class="kwrd"&gt;int&lt;/span&gt; index )&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class="alt"&gt;            Debug.Assert( cmd != &lt;span class="kwrd"&gt;null&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt;( &lt;span class="kwrd"&gt;value&lt;/span&gt; == &lt;span class="kwrd"&gt;null&lt;/span&gt; )&lt;/pre&gt;
&lt;pre class="alt"&gt;            {&lt;/pre&gt;
&lt;pre&gt;                ((IDataParameter)cmd.Parametersindex).Value = DBNull.Value;&lt;/pre&gt;
&lt;pre class="alt"&gt;            }&lt;/pre&gt;
&lt;pre&gt;            &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;            {&lt;/pre&gt;
&lt;pre&gt;                var uintValue = (&lt;span class="kwrd"&gt;uint&lt;/span&gt;)&lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;/pre&gt;
&lt;pre class="alt"&gt;                ( (IDataParameter) cmd.Parametersindex ).Value = (&lt;span class="kwrd"&gt;long&lt;/span&gt;) uintValue;&lt;/pre&gt;
&lt;pre&gt;            }&lt;/pre&gt;
&lt;pre class="alt"&gt;        }&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; DeepCopy( &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt; )&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class="alt"&gt;            &lt;span class="rem"&gt;// we can ignore it...&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;/pre&gt;
&lt;pre class="alt"&gt;        }&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; Replace( &lt;span class="kwrd"&gt;object&lt;/span&gt; original, &lt;span class="kwrd"&gt;object&lt;/span&gt; target, &lt;span class="kwrd"&gt;object&lt;/span&gt; owner )&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class="alt"&gt;            &lt;span class="rem"&gt;// we can ignore it...&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; original;&lt;/pre&gt;
&lt;pre class="alt"&gt;        }&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; Assemble( &lt;span class="kwrd"&gt;object&lt;/span&gt; cached, &lt;span class="kwrd"&gt;object&lt;/span&gt; owner )&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class="alt"&gt;            &lt;span class="rem"&gt;// we can ignore it...&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; cached;&lt;/pre&gt;
&lt;pre class="alt"&gt;        }&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; Disassemble( &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt; )&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class="alt"&gt;            &lt;span class="rem"&gt;// we can ignore it...&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;/pre&gt;
&lt;pre class="alt"&gt;        }&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;bool&lt;/span&gt; IUserType.Equals( &lt;span class="kwrd"&gt;object&lt;/span&gt; x, &lt;span class="kwrd"&gt;object&lt;/span&gt; y )&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt;.Equals( x, y );&lt;/pre&gt;
&lt;pre&gt;        }&lt;/pre&gt;
&lt;pre class="alt"&gt;} &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;There are really two parts of the code that are interesting. SqlTypes / ReturnedType properties which tell NHibernate which types to expect on both sides of the mapping, and the NullSafeGet / NullSafeSet methods which perform the actual conversion.&lt;/p&gt;
&lt;p&gt;Now we just need to plug our custom user type to the mapping, and it goes like this:&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="html"&gt;xml&lt;/span&gt; &lt;span class="attr"&gt;version&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt;?&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;hibernate-mapping&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;urn:nhibernate-mapping-2.2&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;                   &lt;span class="attr"&gt;assembly&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;NHibernate.Test&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;                   &lt;span class="attr"&gt;namespace&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;NHibernate.Test&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;class&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;ClassWithUintProperty&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;id&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Id&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UIntProp&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;not-null&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Foo.Namespace.UIntAsLong, Foo.Assembly&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;class&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;hibernate-mapping&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://nhforge.org/aggbug.aspx?PostID=525" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/S5Du1lSuKhvKvmTk3TjNTjz5eL4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/S5Du1lSuKhvKvmTk3TjNTjz5eL4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/S5Du1lSuKhvKvmTk3TjNTjz5eL4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/S5Du1lSuKhvKvmTk3TjNTjz5eL4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/NHibernateBlog/~4/IEE_MsXdGEE" height="1" width="1"/&gt;</description><category domain="http://nhforge.org/blogs/nhibernate/archive/tags/mapping/default.aspx">mapping</category><category domain="http://nhforge.org/blogs/nhibernate/archive/tags/IUserType/default.aspx">IUserType</category><feedburner:origLink>http://nhforge.org/blogs/nhibernate/archive/2009/10/15/mapping-different-types-iusertype.aspx</feedburner:origLink></item><item><title>NHibernate Validator 1.2 Beta2 released</title><link>http://feedproxy.google.com/~r/NHibernateBlog/~3/BKVYqIn6aig/nhibernate-validator-1-2-beta2-released.aspx</link><pubDate>Sat, 10 Oct 2009 18:16:00 GMT</pubDate><guid isPermaLink="false">45f813f2-f1c4-4eda-a619-288e3cadc793:523</guid><dc:creator>Dario Quintana</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://nhforge.org/blogs/nhibernate/rsscomments.aspx?PostID=523</wfw:commentRss><comments>http://nhforge.org/blogs/nhibernate/archive/2009/10/10/nhibernate-validator-1-2-beta2-released.aspx#comments</comments><description>&lt;p&gt;&lt;img src="http://darioquintana.com.ar/files/NHV-logo-white-background.png" alt="" /&gt;

&lt;/p&gt;
&lt;p&gt;Download NHibernate Validator 1.2 beta2 with sources, binaries and example here &lt;a href="https://sourceforge.net/projects/nhcontrib/files"&gt;here&lt;/a&gt;

&lt;/p&gt;
&lt;p&gt;For use it with NHibernate 2.1 GA.
&lt;/p&gt;
&lt;p&gt;
Enjoy it !&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://nhforge.org/aggbug.aspx?PostID=523" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/CobsfbsNGISZBBQqG6VDixSSczw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CobsfbsNGISZBBQqG6VDixSSczw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/CobsfbsNGISZBBQqG6VDixSSczw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CobsfbsNGISZBBQqG6VDixSSczw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/NHibernateBlog/~4/BKVYqIn6aig" height="1" width="1"/&gt;</description><category domain="http://nhforge.org/blogs/nhibernate/archive/tags/validation/default.aspx">validation</category><category domain="http://nhforge.org/blogs/nhibernate/archive/tags/News/default.aspx">News</category><category domain="http://nhforge.org/blogs/nhibernate/archive/tags/Validator/default.aspx">Validator</category><feedburner:origLink>http://nhforge.org/blogs/nhibernate/archive/2009/10/10/nhibernate-validator-1-2-beta2-released.aspx</feedburner:origLink></item><item><title>Part 10: Testing and Refactoring</title><link>http://feedproxy.google.com/~r/NHibernateBlog/~3/r3XXcAw0zys/part-10-testing-and-refactoring.aspx</link><pubDate>Sun, 20 Sep 2009 19:07:41 GMT</pubDate><guid isPermaLink="false">45f813f2-f1c4-4eda-a619-288e3cadc793:514</guid><dc:creator>Jason Dentler</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://nhforge.org/blogs/nhibernate/rsscomments.aspx?PostID=514</wfw:commentRss><comments>http://nhforge.org/blogs/nhibernate/archive/2009/09/20/part-10-testing-and-refactoring.aspx#comments</comments><description>&lt;p&gt;&lt;strike&gt;Today’s post will be short&lt;/strike&gt;. I’m going to cover the basics of testing with Rhino Mocks and do some refactoring in the DAOs. &lt;/p&gt;  &lt;p&gt;I’m not an expert. This is just how I do things. If you have a better way, do it your way. Better yet, tell me about it so I can improve the way I work as well.&lt;/p&gt;  &lt;h3&gt;Testing Terminology&lt;/h3&gt;  &lt;p&gt;In recent years, testing vocabulary has exploded. There are mocks and stubs and fakes and unit tests and integration tests and acceptance tests and all sorts of jargon. You may be thinking “who cares?” This jargon is only important when code needs to communicate its intent to humans, right?. The compiler doesn’t care what terminology we use. Well, sorry. Code is written for humans, not compilers, so programming jargon is a prerequisite.&lt;/p&gt;  &lt;h4&gt;Test Doubles&lt;/h4&gt;  &lt;p&gt;So, let’s go over some common terms. I’m going to lift these definitions straight from Marton Fowler’s &lt;a href="http://martinfowler.com/articles/mocksArentStubs.html#TheDifferenceBetweenMocksAndStubs" target="_blank"&gt;Mocks Aren’t Stubs&lt;/a&gt;. Test Double is a “generic term for any kind of pretend object used in place of a real object for testing purposes.” That’s pretty straight forward. Test doubles come in four types:&lt;/p&gt;  &lt;blockquote&gt;   &lt;ul&gt;     &lt;li&gt;&lt;b&gt;Dummy&lt;/b&gt; objects are passed around but never actually used. Usually they are just used to fill parameter lists. &lt;/li&gt;      &lt;li&gt;&lt;b&gt;Fake&lt;/b&gt; objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an &lt;a href="http://www.martinfowler.com/bliki/InMemoryTestDatabase.html"&gt;in memory database&lt;/a&gt; is a good example). &lt;/li&gt;      &lt;li&gt;&lt;b&gt;Stubs&lt;/b&gt; provide canned answers to calls made during the test, usually not responding at all to anything outside what&amp;#39;s programmed in for the test. Stubs may also record information about calls, such as an email gateway stub that remembers the messages it &amp;#39;sent&amp;#39;, or maybe only how many messages it &amp;#39;sent&amp;#39;. &lt;/li&gt;      &lt;li&gt;&lt;b&gt;Mocks&lt;/b&gt; are what we are talking about here: objects pre-programmed with expectations which form a specification of the calls they are expected to receive. &lt;/li&gt;   &lt;/ul&gt; &lt;/blockquote&gt;  &lt;p&gt;Hi. Still with me? Good. &lt;/p&gt;  &lt;p&gt;Mocks are significant. They are part of the “proof” of the test. The other three amount to plumbing. Now, you may be asking your self why we even need test doubles. Why can’t we just run our production code and inspect the output? &lt;a href="http://martinfowler.com/articles/mocksArentStubs.html#ClassicalAndMockistTesting" target="_blank"&gt;Fowler’s article has several sections&lt;/a&gt; about the differences and pros and cons of classical testing (using objects from the real code) vs. mockist testing (creating doubles for everything except what you’re testing).&lt;/p&gt;  &lt;p&gt;Even in classical testing, you sometimes have to swap in a test double for objects that lead to permanent side effects or operate too slowly. In mockist testing, you swap in test doubles for everything that you’re not explicitly testing. Either way, you need to know how to create and use test doubles.&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;margin-left:0px;border-left-width:0px;margin-right:0px;" border="0" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/NewRhinoMocksLogo_ECFE/rhinomocks-120x90.png" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;We’re going to use &lt;a href="http://ayende.com/projects/rhino-mocks.aspx" target="_blank"&gt;Rhino Mocks&lt;/a&gt;, a fluent framework for creating stubs and mocks. I don’t know if it’s the best, but if Ayende wrote it, you can bet it’s pretty darn awesome. Plus, the fluent syntax works OK in VB.NET, which is rare. &lt;/p&gt;  &lt;h3&gt;Writing the Test&lt;/h3&gt;  &lt;p&gt;Suppose we had a standard GetByID function on our DAO (because we do) containing some code like this (because it does). How would we test that the function actually did what it claimed? &lt;/p&gt;  &lt;pre class="brush:vbnet"&gt;        If m_Session.Transaction Is Nothing OrElse Not m_Session.Transaction.IsActive Then
            Dim RetVal As TEntity
            Using Tran = m_Session.BeginTransaction
                RetVal = m_Session.Get(Of TEntity)(ID)
                Tran.Commit()
                Return RetVal
            End Using
        Else
            Return m_Session.Get(Of TEntity)(ID)
        End If&lt;/pre&gt;

&lt;pre class="brush:csharp"&gt;            if (null == m_Session.Transaction || !m_Session.Transaction.IsActive)
            {
                TEntity retval;
                using (var Tran = m_Session.BeginTransaction())
                {
                    retval = m_Session.Get&amp;lt;TEntity&amp;gt;(ID);
                    Tran.Commit();
                    return retval;
                }
            }
            else
            {
                return m_Session.Get&amp;lt;TEntity&amp;gt;(ID);
            }&lt;/pre&gt;

&lt;p&gt;Because I’m not an expert, I won’t try to explain the computer science of testing. I can tell you that if we ignore possible branches inside NHibernate objects, there are two possible paths through our function (the first if we don’t have an existing explicit transaction, and the second if we do), giving us a &lt;a href="http://en.wikipedia.org/wiki/Cyclomatic_complexity" target="_blank"&gt;cyclomatic complexity&lt;/a&gt; of 2. This means that we need two unit tests to achieve 100% code coverage. 100% code coverage doesn’t mean perfect code, but it helps.&lt;/p&gt;

&lt;p&gt;I prefer the Record / Playback style of testing. In this style, you start by setting up your expectations within a record section – which mock methods will be called, how many times they’ll be called, in what order they’ll be called, and what their return values should be. Then, in the playback section, you perform the actual action. In this case, we’ll create an instance of our DAO and call its GetByID method. Finally, you verify that the expectations of your mock were met, as well as any other assertions you may need to prove.&lt;/p&gt;

&lt;p&gt;Edit: The alternative to Record / Playback is Arrange / Act / Assert. If you don’t know the difference, &lt;a href="http://rasmuskl.dk/post/Why-AAA-style-mocking-is-better-than-Record-Playback.aspx" target="_blank"&gt;here’s a good article&lt;/a&gt; Jose sent me. Rhino Mocks supports both styles. I still prefer Record / Playback, probably just because I’m used to it.&lt;/p&gt;

&lt;p&gt;Here’s what a test of GetByID with a pre-existing transaction would look like:&lt;/p&gt;

&lt;pre class="brush:vbnet"&gt;    &amp;lt;Test()&amp;gt; _
    Public Sub GetByIDTest()
        Dim mocks As New MockRepository()
        Dim session As NHibernate.ISession = mocks.StrictMock(Of NHibernate.ISession)()
        Dim transaction As NHibernate.ITransaction = mocks.Stub(Of NHibernate.ITransaction)()
        Dim expected As Student = mocks.Stub(Of Student)()
        Dim actual As Student
        Using mocks.Record()
            Rhino.Mocks.Expect.Call(session.Transaction).Return(transaction).Repeat.Any()
            Rhino.Mocks.Expect.Call(transaction.IsActive).Return(True)
            Rhino.Mocks.Expect.Call(session.Get(Of Student)(Guid.Empty)).Return(expected)
        End Using

        Using mocks.Playback()
            Dim StudentDao As IReadStudent = New StudentDaoImpl(session)
            actual = StudentDao.GetByID(Guid.Empty)
        End Using
        mocks.VerifyAll()
        Assert.IsNotNull(actual, &amp;quot;null entity returned&amp;quot;)
        Assert.AreSame(expected, actual, &amp;quot;wrong entity returned&amp;quot;)
    End Sub&lt;/pre&gt;

&lt;pre class="brush:csharp"&gt;        [Test]
        public void GetByIDTest()
        {
            MockRepository mocks = new MockRepository();
            NHibernate.ISession session = mocks.StrictMock&amp;lt;NHibernate.ISession&amp;gt;();
            NHibernate.ITransaction transaction = mocks.Stub&amp;lt;NHibernate.ITransaction&amp;gt;();
            Student expected = new Student();
            Student actual;
            using (mocks.Record())
            {
                Rhino.Mocks.Expect.Call(session.Transaction)
                    .Return(transaction)
                    .Repeat.Any();
                Rhino.Mocks.Expect.Call(transaction.IsActive)
                    .Return(true);
                Rhino.Mocks.Expect.Call(session.Get&amp;lt;Student&amp;gt;(Guid.Empty))
                    .Return(expected);
            }
            using (mocks.Playback())
            {
                IReadStudent StudentDao = new StudentDAOImpl(session);
                actual = StudentDao.GetById(Guid.Empty);
            }
            mocks.VerifyAll();
            Assert.IsNotNull(actual);
            Assert.AreSame(expected,actual);
        }&lt;/pre&gt;

&lt;p&gt;We start by creating a MockRepository. This is the factory for all of our mocks and stubs, controls our record and playback blocks, and verifies that all the mock expectations have been met.&lt;/p&gt;

&lt;p&gt;Next, we create a mock of the &lt;a href="http://nhforge.org" target="_blank"&gt;NHIbernate&lt;/a&gt; session and a stub of an NHibernate transaction. We create a mock because we want to make sure our DAO calls m_Session.Get&amp;lt;&amp;gt;. We also create a double for our return value called expected. We’ll compare it to the actual return value. &lt;/p&gt;

&lt;p&gt;Now that we have our doubles, we set up our expectations. We are testing the path of the pre-existing transaction. Session.transaction will return our transaction stub. Since this is a mock, not a stub, the default is to assert that it is called exactly once. Since we’re not interested in this part, we specify that it can be called &lt;strong&gt;any&lt;/strong&gt; number of times. We also specify that a call to transaction.IsActive should return true. Finally, we specify that our DAO will call session.Get&amp;lt;&amp;gt; exactly once, and that our mock session should return our expected student.&lt;/p&gt;

&lt;p&gt;Next, we start our playback block and perform the action. We create an instance of our DAO, passing in the mock session we wired up in our record block, and we call GetByID. &lt;/p&gt;

&lt;p&gt;Finally, we verify that our DAO interacted with the stub as expected. We also assert that the actual instance returned during our test is the same as our expected instance.&lt;/p&gt;

&lt;p&gt;This covers the first test. What about the second one? Well, the test would be identical except for your expectations. We would setup our transaction stub so that transaction.IsActive returned false. We would also expect our DAO to call session.BeginTransaction(). &lt;/p&gt;

&lt;p&gt;Now, I’m lazy and we’ve already done things backwards by writing our code before our tests, so let’s continue being lazy. I don’t want to write two tests for each DAO method just because of some transaction handling code, which by the way, is repeated all over the place. Not good. Let’s refactor things a bit.&lt;/p&gt;

&lt;h3&gt;Refactored Transaction Handling&lt;/h3&gt;

&lt;p&gt;In all of the DAO methods, I’ve made the choice to ensure we have an explicit transaction before interacting with the database. In previous versions, each method is nearly identical to the code we tested above above.&lt;/p&gt;

&lt;p&gt;In all of this, the only unique code is the call to m_Session.Get(). The rest of the code is just uninteresting transaction handling, and this uninteresting plumbing code is repeated in every method of our DAO. Let’s pull it out in to its own function.&lt;/p&gt;

&lt;pre class="brush:vbnet"&gt;    Protected Function WrapInTransaction(ByVal F As Func(Of TEntity)) As TEntity
        Return WrapInTransaction(Of TEntity)(F)
    End Function

    Protected Function WrapInTransaction(Of TResult)(ByVal F As Func(Of TResult)) As TResult
        If m_Session.Transaction Is Nothing OrElse _
            m_Session.Transaction.IsActive = False Then
            Using Tran = m_Session.BeginTransaction
                Dim RetVal As TResult = F.Invoke()
                Tran.Commit()
                Return RetVal
            End Using
        Else
            Return F.Invoke()
        End If
    End Function&lt;/pre&gt;

&lt;pre class="brush:csharp"&gt;        protected TEntity WrapInTransaction(System.Func&amp;lt;TEntity&amp;gt; F)
        {
            return WrapInTransaction&amp;lt;TEntity&amp;gt;(F);
        }

        protected TResult WrapInTransaction&amp;lt;TResult&amp;gt;(System.Func&amp;lt;TResult&amp;gt; F)
        {
            if (null == m_Session.Transaction || !m_Session.Transaction.IsActive)
            {
                using (NHibernate.ITransaction Tran = m_Session.BeginTransaction())
                {
                    TResult RetVal = F.Invoke();
                    Tran.Commit();
                    return RetVal;
                }
            }
            else
            {
                return F.Invoke();
            }
        }&lt;/pre&gt;
Now we can pass in the small-but-interesting bit of code as a parameter to the WrapInTransaction method. This lets us simplify our methods down to this: 

&lt;pre class="brush:vbnet"&gt;    Public Function GetByID(ByVal ID As System.Guid) As TEntity Implements IRead(Of TEntity).GetByID
        Return WrapInTransaction(Function() m_Session.Get(Of TEntity)(ID))
    End Function&lt;/pre&gt;

&lt;pre class="brush:csharp"&gt;        public TEntity GetById(System.Guid ID)
        {
            return WrapInTransaction(() =&amp;gt; m_Session.Get&amp;lt;TEntity&amp;gt;(ID));
        }&lt;/pre&gt;

&lt;p&gt;It’s shorter. Some might argue that it’s not as readable since it uses lambda syntax. In this case, I think DRY (don’t repeat yourself) is more important. To be honest, I’m not sure if this cuts the cyclomatic complexity of our methods in half, but It certainly lets us write about 1/2 as many tests and still have 100% coverage. We just need to write our already-have-a-transaction and wrap-in-transaction tests once period, instead of once per method.&lt;/p&gt;

&lt;p&gt;If you’re working in C#, you can create another overload that accepts a System.Action (System.Func but returning void). In Visual Basic.NET, this would be a Sub, but unfortunately, there’s no lambda syntax for calling a Sub in VB.NET. To get around this, I’ve updated our Save method to this:&lt;/p&gt;

&lt;pre class="brush:vbnet"&gt;    Public Function Save(ByVal Entity As TEntity) As TEntity Implements ISave(Of TEntity).Save
        Return WrapInTransaction(Function() SaveOrUpdate(Entity))
    End Function

    Private Function SaveOrUpdate(ByVal Entity As TEntity) As TEntity
        m_Session.SaveOrUpdate(Entity)
        Return Entity
    End Function&lt;/pre&gt;
Since we&amp;#39;re returning a value, we can use our existing WrapInTransaction(Func&amp;lt;&amp;gt;) method. The download includes tests for all of our DAO methods, including WrapInTransaction. 

&lt;p&gt;That’s it for part 10. For homework, write the tests for our StudentDaoImpl class. Hints: Use a fake, verify that it returns what it should, and verify that it doesn’t return what it shouldn’t.&lt;/p&gt;

&lt;p&gt;I’ve changed the SQLiteDatabaseScope to match my previous post, and pulled it in to its own project. &lt;/p&gt;

&lt;p&gt;Download the entire solution in &lt;a href="http://jasondentler.com/downloads/NStackExample.Part10.VBNET.zip" target="_blank"&gt;VB.NET&lt;/a&gt; or &lt;a href="http://jasondentler.com/downloads/NStackExample.Part10.CSharp.zip" target="_blank"&gt;C#&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In part 11, we’ll dive in to validation.&lt;/p&gt;

&lt;p&gt;Jason&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://nhforge.org/aggbug.aspx?PostID=514" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/WvpLw9Y7G_lUAqynse3mhkwvZik/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WvpLw9Y7G_lUAqynse3mhkwvZik/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/WvpLw9Y7G_lUAqynse3mhkwvZik/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WvpLw9Y7G_lUAqynse3mhkwvZik/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/NHibernateBlog/~4/r3XXcAw0zys" height="1" width="1"/&gt;</description><feedburner:origLink>http://nhforge.org/blogs/nhibernate/archive/2009/09/20/part-10-testing-and-refactoring.aspx</feedburner:origLink></item><item><title>Part 9: NHibernate transactions</title><link>http://feedproxy.google.com/~r/NHibernateBlog/~3/hKObd6iciMs/part-9-nhibernate-transactions.aspx</link><pubDate>Tue, 08 Sep 2009 13:26:05 GMT</pubDate><guid isPermaLink="false">45f813f2-f1c4-4eda-a619-288e3cadc793:504</guid><dc:creator>Jason Dentler</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://nhforge.org/blogs/nhibernate/rsscomments.aspx?PostID=504</wfw:commentRss><comments>http://nhforge.org/blogs/nhibernate/archive/2009/09/08/part-9-nhibernate-transactions.aspx#comments</comments><description>&lt;p&gt;In this part, we’re going to wrap our &lt;a href="http://nhforge.org" target="_blank"&gt;NHibernate&lt;/a&gt; transactions and create a factory for them so we can use them in higher layers without referencing NHibernate all the way up.&lt;/p&gt;  &lt;p&gt;If you’re new to the series, you can read &lt;a href="http://jasondentler.com/blog/2009/08/how-to-using-the-n-stack-part-1/" target="_blank"&gt;Part 1&lt;/a&gt;, &lt;a href="http://jasondentler.com/blog/2009/08/how-to-using-the-n-stack-part-2/" target="_blank"&gt;Part 2&lt;/a&gt;, &lt;a href="http://jasondentler.com/blog/2009/08/how-to-using-the-n-stack-part-3/" target="_blank"&gt;Part 3&lt;/a&gt;, &lt;a href="http://jasondentler.com/blog/2009/08/how-to-using-the-n-stack-part-4/" target="_blank"&gt;Part 4&lt;/a&gt;, &lt;a href="http://jasondentler.com/blog/2009/08/part-5-fixing-the-broken-stuff/" target="_blank"&gt;Part 5&lt;/a&gt;, &lt;a href="http://jasondentler.com/blog/2009/08/part-6-ninject-and-mvc-or-how-to-be-a-web-ninja/" target="_blank"&gt;Part 6&lt;/a&gt;, &lt;a href="http://jasondentler.com/blog/2009/08/part-7-nhibernate-and-ninject-for-asp-net-mvc/" target="_blank"&gt;Part 7&lt;/a&gt;, and &lt;a href="http://jasondentler.com/blog/2009/09/part-8-daos-repositories-or-query-objects" target="_blank"&gt;Part 8&lt;/a&gt; to catch up.&lt;/p&gt;  &lt;p&gt;You may have noticed in part 8 that in each DAO method, if we didn’t already have an explicit transaction, I created one around each database interaction. My reason for this is explained in Ayende’s NHibernate Profiler alert “&lt;a href="http://nhprof.com/Learn/Alert?name=DoNotUseImplicitTransactions" target="_blank"&gt;Use of implicit transactions is discouraged&lt;/a&gt;.” This works great for simple DB interaction, but what about the more complex scenarios? &lt;/p&gt;  &lt;p&gt;This is where we get to talk about this great thing called a business transaction. So once again, I’m going to parade out my experts. Actually, this time it’s only Udi Dahan. There are two key points he’s written about on his blog. &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://www.udidahan.com/2009/01/24/ddd-many-to-many-object-relational-mapping/" target="_blank"&gt;Partial failures can be good&lt;/a&gt;. The programmer in all of us sees that and screams &lt;a href="http://en.wikipedia.org/wiki/ACID" target="_blank"&gt;atomicity&lt;/a&gt;. Transactions&amp;#160; should be all-or-nothing. Anything less is just wrong. Right? In real life, there are instances where we allow, and even prefer partial failures of business transactions. Udi gives us a great example. Would you leave the grocery store empty handed simply because they were out of one item on your list? Probably not. When you’re gathering requirements, be sure to ask questions about the proper way to fail. “Roll it all back” isn’t the only option. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.udidahan.com/2007/01/22/realistic-concurrency/" target="_blank"&gt;Realistic Concurrency&lt;/a&gt; – The entire post is worth reading, but Udi makes one point I want to touch on specifically. When performing an operation for the user, you should get the current state, validate, and then perform the task all within the business transaction. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Let’s use our college application as an example. We have a user story / use case / requirement / story card / whatever to allow students to register for classes, provided those classes aren’t full. If you’ve ever worked at or attended a college or university where certain classes always have more demand than available seats, you are no doubt aware of how quickly those classes will fill up. In fact, the best sections (best professors and best times) can fill up just minutes after registration is opened. It’s very possible that dozens of potential students could access the section when there is only a few seats left. Since the enrollment in a particular section (the current state) changes so rapidly, you must obtain a lock, refresh your enrollment numbers and make sure there is room (revalidate) before actually enrolling that student. If more than one registration request is received, they should be performed serially. &lt;/p&gt;  &lt;p&gt;The process is:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Open a transaction at the proper &lt;a href="http://en.wikipedia.org/wiki/Isolation_(database_systems)" target="_blank"&gt;isolation level&lt;/a&gt;. Consult your nearest DBA, as isolation levels are outside the scope of this series. &lt;/li&gt;    &lt;li&gt;Refresh – Get the current state of the entity &lt;/li&gt;    &lt;li&gt;(Re)Validate – Be sure the business transaction is still valid for the current state &lt;/li&gt;    &lt;li&gt;Execute – Perform the insert / update / delete &lt;/li&gt;    &lt;li&gt;Commit the transaction &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Now that we’ve covered business transactions, let’s get set up to use them in our business logic. We shouldn’t have NHibernate types floating around at that level, so we’ll wrap them. Once again, the interfaces go in the Data namespace of the core project and the implementations go in the Data project.&lt;/p&gt;  &lt;pre class="brush:vbnet"&gt;Imports System.Data

Namespace Data

    Public Interface ITransactionFactory

        Function BeginTransaction() As ITransaction
        Function BeginTransaction(ByVal IsolationLevel As IsolationLevel) As ITransaction

    End Interface

End Namespace

Namespace Data

    Public Interface ITransaction
        Inherits IDisposable

        Sub Commit()
        Sub Rollback()

    End Interface

End Namespace

Imports NHibernate

Public Class TransactionFactoryImpl
    Implements ITransactionFactory

    Public Sub New(ByVal Session As ISession)
        m_Session = Session
    End Sub

    Protected ReadOnly m_Session As ISession

    Public Function BeginTransaction() As ITransaction Implements ITransactionFactory.BeginTransaction
        Return New TransactionWrapper(m_Session.BeginTransaction)
    End Function

    Public Function BeginTransaction(ByVal IsolationLevel As System.Data.IsolationLevel) As ITransaction Implements ITransactionFactory.BeginTransaction
        Return New TransactionWrapper(m_Session.BeginTransaction(IsolationLevel))
    End Function

End Class


Imports NHibernate

Public Class TransactionWrapper
    Implements ITransaction

    Public Sub New(ByVal Transaction As NHibernate.ITransaction)
        m_Transaction = Transaction
    End Sub

    Protected ReadOnly m_Transaction As NHibernate.ITransaction

    Public Sub Commit() Implements ITransaction.Commit
        m_Transaction.Commit()
    End Sub

    Public Sub Rollback() Implements ITransaction.Rollback
        m_Transaction.Rollback()
    End Sub

    Private disposedValue As Boolean = False        &amp;#39; To detect redundant calls

    &amp;#39; IDisposable
    Protected Overridable Sub Dispose(ByVal disposing As Boolean)
        If Not Me.disposedValue Then
            If disposing Then
                &amp;#39; TODO: free other state (managed objects).
                m_Transaction.Dispose()
            End If

            &amp;#39; TODO: free your own state (unmanaged objects).
            &amp;#39; TODO: set large fields to null.
        End If
        Me.disposedValue = True
    End Sub

#Region &amp;quot; IDisposable Support &amp;quot;
    &amp;#39; This code added by Visual Basic to correctly implement the disposable pattern.
    Public Sub Dispose() Implements IDisposable.Dispose
        &amp;#39; Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
#End Region

End Class&lt;/pre&gt;

&lt;pre class="brush:csharp"&gt;using System.Data;

namespace NStackExample.Data
{
    public interface ITransactionFactory
    {

        ITransaction BeginTransaction();
        ITransaction BeginTransaction(IsolationLevel isolationLevel);

    }
}

using System;

namespace NStackExample.Data
{
    public interface ITransaction : IDisposable 
    {
        void Commit();
        void Rollback();
    }
}

using System.Data;
using NHibernate;

namespace NStackExample.Data
{
    public class TransactionFactoryImpl : ITransactionFactory 
    {

        public TransactionFactoryImpl(ISession Session)
        {
            m_Session = Session;
        }
        
        protected readonly ISession m_Session;

        #region ITransactionFactory Members

        public ITransaction BeginTransaction()
        {
            return new TransactionWrapper(m_Session.BeginTransaction());
        }

        public ITransaction BeginTransaction(IsolationLevel isolationLevel)
        {
            return new TransactionWrapper(m_Session.BeginTransaction(isolationLevel));
        }

        #endregion
    }
}


using System;
using NHibernate;

namespace NStackExample.Data
{
    public class TransactionWrapper : ITransaction
    {

        public TransactionWrapper(NHibernate.ITransaction Transaction)
        {
            m_Transaction = Transaction;
        }

        protected readonly NHibernate.ITransaction m_Transaction;

        #region ITransaction Members

        void ITransaction.Commit()
        {
            m_Transaction.Commit();
        }

        void ITransaction.Rollback()
        {
            m_Transaction.Rollback();
        }

        private bool disposedValue = false;

        protected override void Dispose(bool Disposing)
        {
            if (!this.disposedValue)
            {
                m_Transaction.Dispose();
            }
            this.disposedValue = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        #endregion
    }
}&lt;/pre&gt;

&lt;p&gt;You may be interested to know that the NHibernate ITransaction will perform an implicit rollback when it is disposed, unless an explicit call to Commit or Rollback has already occurred. To implement this behavior, we implement IDisposable in our transaction wrapper and chain our wrapper’s Dispose to NHibernate.ITransaction’s Dispose. This implicit rollback can indicate a missing call to Commit, so it &lt;a href="http://nhprof.com/Learn/Alert?name=AvoidImplicitRollback" target="_blank"&gt;generates an alert in NHibernate Profiler&lt;/a&gt;. If you intend to rollback, do it explicitly. Your code will be easier to understand.&lt;/p&gt;

&lt;p&gt;That’s it for part 9.&lt;/p&gt;

&lt;p&gt;Jason 
  &lt;br /&gt;- Off to mow the lawn.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://nhforge.org/aggbug.aspx?PostID=504" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Rf7FEiY8qPTcJI9rLYrN3zubwAw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Rf7FEiY8qPTcJI9rLYrN3zubwAw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Rf7FEiY8qPTcJI9rLYrN3zubwAw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Rf7FEiY8qPTcJI9rLYrN3zubwAw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/NHibernateBlog/~4/hKObd6iciMs" height="1" width="1"/&gt;</description><feedburner:origLink>http://nhforge.org/blogs/nhibernate/archive/2009/09/08/part-9-nhibernate-transactions.aspx</feedburner:origLink></item><item><title>Part 8: DAOs, Repositories, or Query Objects</title><link>http://feedproxy.google.com/~r/NHibernateBlog/~3/nG6mJ9D8N1M/part-8-daos-repositories-or-query-objects.aspx</link><pubDate>Mon, 07 Sep 2009 20:17:50 GMT</pubDate><guid isPermaLink="false">45f813f2-f1c4-4eda-a619-288e3cadc793:502</guid><dc:creator>Jason Dentler</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://nhforge.org/blogs/nhibernate/rsscomments.aspx?PostID=502</wfw:commentRss><comments>http://nhforge.org/blogs/nhibernate/archive/2009/09/07/part-8-daos-repositories-or-query-objects.aspx#comments</comments><description>&lt;p&gt;Part 8 is about abstracting &lt;a href="http://nhforge.org" target="_blank"&gt;NHibernate&lt;/a&gt;. Catch up by reading &lt;a href="http://jasondentler.com/blog/2009/08/how-to-using-the-n-stack-part-1/" target="_blank"&gt;Part 1&lt;/a&gt;, &lt;a href="http://jasondentler.com/blog/2009/08/how-to-using-the-n-stack-part-2/" target="_blank"&gt;Part 2&lt;/a&gt;, &lt;a href="http://jasondentler.com/blog/2009/08/how-to-using-the-n-stack-part-3/" target="_blank"&gt;Part 3&lt;/a&gt;, &lt;a href="http://jasondentler.com/blog/2009/08/how-to-using-the-n-stack-part-4/" target="_blank"&gt;Part 4&lt;/a&gt;, &lt;a href="http://jasondentler.com/blog/2009/08/part-5-fixing-the-broken-stuff/" target="_blank"&gt;Part 5&lt;/a&gt;, &lt;a href="http://jasondentler.com/blog/2009/08/part-6-ninject-and-mvc-or-how-to-be-a-web-ninja/" target="_blank"&gt;Part 6&lt;/a&gt;, and &lt;a href="http://jasondentler.com/blog/2009/08/part-7-nhibernate-and-ninject-for-asp-net-mvc/" target="_blank"&gt;Part 7&lt;/a&gt;. &lt;/p&gt;  &lt;div&gt;&lt;em&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;margin-left:0px;border-left-width:0px;margin-right:0px;" border="0" align="left" src="http://commons.wikimedia.org/w/thumb.php?f=Nuvola%20apps%20important%20yellow.svg&amp;amp;width=200px" width="100" height="84" alt="" /&gt;Warning: This post will contain an extraordinary number of links. They will lead you to the opinions of very smart people™. Click them. Read them. Learn something new.&lt;/em&gt;&lt;/div&gt;  &lt;div&gt;There is no one best practice. I know. I googled for it. It seems there are just as many patterns as there are anti-patterns. In fact, these days we’re not even clear &lt;a href="http://msdn.microsoft.com/en-us/library/aa973811.aspx" target="_blank"&gt;which&lt;/a&gt; is &lt;a href="http://ayende.com/Blog/archive/2009/04/17/repository-is-the-new-singleton.aspx" target="_blank"&gt;which&lt;/a&gt;. There are &lt;a href="http://codebetter.com/blogs/gregyoung/archive/2009/04/23/repository-is-dead-long-live-repository.aspx" target="_blank"&gt;differing opinions&lt;/a&gt; all &lt;a href="http://www.udidahan.com/2007/03/28/query-objects-vs-methods-on-a-repository/" target="_blank"&gt;over&lt;/a&gt; the &lt;a href="http://geekswithblogs.net/Billy/archive/2006/02/15/69607.aspx" target="_blank"&gt;place&lt;/a&gt;.&lt;/div&gt;  &lt;h3&gt;What are my options?&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://martinfowler.com/eaaCatalog/repository.html" target="_blank"&gt;Repositories&lt;/a&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://twitter.com/sbohlen" target="_blank"&gt;Steve Bohlen&lt;/a&gt; uses the repository pattern. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://twitter.com/jfroma" target="_blank"&gt;José Romaniello&lt;/a&gt; &lt;a href="http://jfromaniello.blogspot.com/2009/08/chinook-media-manager-core.html" target="_blank"&gt;uses repositories&lt;/a&gt; in his Chinook Media Manager sample on NHForge.org &lt;/li&gt;    &lt;li&gt;&lt;a href="http://twitter.com/ayende" target="_blank"&gt;Ayende&lt;/a&gt; &lt;a href="http://msdn.microsoft.com/en-us/library/aa973811.aspx" target="_blank"&gt;loved repositories in 2006&lt;/a&gt;, but not anymore. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html" target="_blank"&gt;Data Access Objects&lt;/a&gt;:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://fabiomaulo.blogspot.com/" target="_blank"&gt;Fabio Maulo&lt;/a&gt; &lt;a href="http://ayende.com/Blog/archive/2009/04/17/repository-is-the-new-singleton.aspx#30272" target="_blank"&gt;uses DAOs&lt;/a&gt; with query objects. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://twitter.com/tehlike" target="_blank"&gt;Tuna Toksoz&lt;/a&gt; uses DAOs with FindBy methods &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://martinfowler.com/eaaCatalog/queryObject.html" target="_blank"&gt;Query objects&lt;/a&gt;:&lt;/p&gt;  &lt;li&gt;In early 2009, Ayende posted that he &lt;a href="http://ayende.com/Blog/archive/2009/04/17/repository-is-the-new-singleton.aspx" target="_blank"&gt;no longer likes repositories,&lt;/a&gt; and has switched to query objects which expose raw NHibernate&amp;#160; ICriteria. &lt;/li&gt;  &lt;li&gt;&lt;a href="http://twitter.com/udidahan" target="_blank"&gt;Udi Dahan&lt;/a&gt; also prefers &lt;a href="http://www.udidahan.com/2007/03/28/query-objects-vs-methods-on-a-repository/" target="_blank"&gt;query objects&lt;/a&gt;     &lt;p&gt;One note about all of this: Repositories and DAOs can both be used with query objects or simple FindBy methods. Query objects can also be used on their own.&lt;/p&gt;    &lt;h3&gt;What’s the score? &lt;/h3&gt;    &lt;p&gt;The experts don’t agree, so use whatever you think will work best for your application and your team. By the way, if you’re not following all of these people on twitter, go follow them now.&lt;/p&gt;    &lt;p&gt;If you’re looking for a good NHibernate repository sample, check out &lt;a href="http://nhforge.org/wikis/howtonh/your-first-nhibernate-based-application.aspx" target="_blank"&gt;Your First NHibernate based application&lt;/a&gt; by Gabriel Schenker on the NHForge wiki, or José’s Chinook WPF app. &lt;/p&gt;    &lt;p&gt;In this sample application, we’re going to use Data Access Objects. The pattern is simple and well known. This application is small and we won’t have many queries, so we’ll use DAOs with FindBy methods. In a large project, such as an ERP, I would use query objects. &lt;/p&gt;    &lt;h3&gt;Splitting the CRUD&lt;/h3&gt;    &lt;p&gt;CRUD stands for create, read/retrieve, update, and delete/destroy. which correspond to SQL INSERT, SELECT, UPDATE, and DELETE respectively. &lt;/p&gt;    &lt;p&gt;Suppose we’re tracking down an issue in our system where the customer’s middle name was being erased from the database. You start with the most likely locations such as the round trip through the customer update view. No luck. You’ll have to dig in deeper.&lt;/p&gt;    &lt;p&gt;We’re using constructor dependency injection throughout our application. Our DAO is defined by the interface IDAO&amp;lt;T&amp;gt;. If you saw some object with a dependency of IDAO&amp;lt;Customer&amp;gt;, you would assume that it performs some database action on customer, so it would be a candidate for deeper investigation. Of course, without diving in to the code, you wouldn’t know what it actually does to customer. &lt;/p&gt;    &lt;p&gt;As it turns out 95% of the uses of IDAO&amp;lt;Customer&amp;gt; only display customer data. They don’t actually change anything. You just wasted a LOT of time digging through code that couldn’t possibly cause your bug.&lt;/p&gt;    &lt;p&gt;Now suppose you had split your IDAO interface to allow more fine-grained dependencies. Instead of IDAO&amp;lt;T&amp;gt;, you now have ICreate&amp;lt;T&amp;gt;, IRead&amp;lt;T&amp;gt;, IUpdate&amp;lt;T&amp;gt;, and IDelete&amp;lt;T&amp;gt;. When searching for a bug like the one I described, you only need to search through classes with dependencies on IUpdate&amp;lt;Customer&amp;gt; and possibly ICreate&amp;lt;Customer&amp;gt;. &lt;/p&gt;    &lt;p&gt;We’re tracking which entity instances are transient (new, not saved) and which ones are already persisted (saved to the database) by the ID property. If the ID is equal to Guid.Empty, the instance is transient. If the ID has any other value, it’s persistent. Since we know that handy bit of information, we don’t really need separate interfaces for create and update operations. We can combine them in to one called ISave&amp;lt;T&amp;gt;. We now have IRead&amp;lt;T&amp;gt;, ISave&amp;lt;T&amp;gt;, and IDelete&amp;lt;T&amp;gt;. &lt;/p&gt;    &lt;p&gt;Even though we’ve split our interface up by operation, we’re still only going to have one DAO implementation. In the &lt;a href="http://ninject.org/" target="_blank"&gt;Ninject&lt;/a&gt; module, we’ll bind each of our three interfaces to the DAO implementation.&lt;/p&gt;    &lt;p&gt;Every entity has the same basic CUD, but what about entity-specific queries? In these cases, we’ll create entity-specific interfaces such as IReadCustomer. This means you could have up to four IoC bindings for each entity. &lt;/p&gt;    &lt;p&gt;Splitting the CRUD operations in to separate interfaces has one added benefit. In our case, we don’t want to allow certain (most) entities to be deleted. In these cases, your entity-specific DAO shouldn’t implement IDelete. For this reason, we won’t implement deletes in our generic base DAO.&lt;/p&gt;    &lt;h3&gt;Show me some code already!&lt;/h3&gt;    &lt;p&gt;We put our interfaces in the data namespace of the core project and our implementations in the data project.&lt;/p&gt;    &lt;pre class="brush:vbnet"&gt;Namespace Data

    Public Interface IRead(Of TEntity As Entity)

        Function GetByID(ByVal ID As Guid) As TEntity

    End Interface

End Namespace

Namespace Data

    Public Interface ISave(Of TEntity As Entity)

        Function Save(ByVal Entity As TEntity) As TEntity

    End Interface

End Namespace

Namespace Data

    Public Interface IDelete(Of TEntity As Entity)

        Sub Delete(ByVal Entity As TEntity)

    End Interface

End Namespace

Namespace Data

    Public Interface IReadStudent
        Inherits IRead(Of Student)

        Function FindByStudentID(ByVal StudentID As String) As Student
        Function FindByName(ByVal LikeFirstName As String, ByVal LikeLastName As String) As IEnumerable(Of Student)

    End Interface

End Namespace

Imports NHibernate

Public Class GenericDAOImpl(Of TEntity As Entity)
    Implements IRead(Of TEntity)
    Implements ISave(Of TEntity)

    Public Sub New(ByVal Session As ISession)
        m_session = Session
    End Sub

    Protected ReadOnly m_Session As ISession

    Public Function GetByID(ByVal ID As System.Guid) As TEntity Implements IRead(Of TEntity).GetByID
        If m_Session.Transaction Is Nothing Then
            Dim RetVal As TEntity
            Using Tran = m_Session.BeginTransaction
                RetVal = m_Session.Get(Of TEntity)(ID)
                Tran.Commit()
                Return RetVal
            End Using
        Else
            Return m_Session.Get(Of TEntity)(ID)
        End If
    End Function

    Public Function Save(ByVal Entity As TEntity) As TEntity Implements ISave(Of TEntity).Save
        If m_Session.Transaction Is Nothing Then
            Using Tran = m_Session.BeginTransaction
                m_Session.SaveOrUpdate(Entity)
                Tran.Commit()
            End Using
        Else
            m_Session.SaveOrUpdate(Entity)
        End If
        Return Entity
    End Function

End Class

Imports NHibernate
Imports NHibernate.Criterion

Public Class StudentDaoImpl
    Inherits GenericDAOImpl(Of Student)
    Implements IReadStudent

    Public Sub New(ByVal Session As ISession)
        MyBase.New(Session)
    End Sub

    Public Function FindByName(ByVal LikeFirstName As String, ByVal LikeLastName As String) As System.Collections.Generic.IEnumerable(Of Student) Implements IReadStudent.FindByName
        Dim crit As ICriteria = m_Session.CreateCriteria(Of Student) _
            .Add(Expression.Like(&amp;quot;FirstName&amp;quot;, LikeFirstName)) _
            .Add(Expression.Like(&amp;quot;LastName&amp;quot;, LikeLastName)) _
            .SetMaxResults(101)
        If m_Session.Transaction Is Nothing Then
            Using Tran = m_Session.BeginTransaction()
                Dim RetVal = crit.List.Cast(Of Student)()
                Tran.Commit()
                Return RetVal
            End Using
        Else
            Return crit.List.Cast(Of Student)()
        End If
    End Function

    Public Function FindByStudentID(ByVal StudentID As String) As Student Implements IReadStudent.FindByStudentID
        Dim Crit = m_Session.CreateCriteria(Of Student) _
            .Add(Expression.Eq(&amp;quot;StudentID&amp;quot;, StudentID))
        If m_Session.Transaction Is Nothing Then
            Using Tran = m_Session.BeginTransaction
                Dim RetVal = Crit.UniqueResult(Of Student)()
                Tran.Commit()
                Return RetVal
            End Using
        Else
            Return Crit.UniqueResult(Of Student)()
        End If
    End Function

End Class&lt;/pre&gt;

  &lt;pre class="brush:csharp"&gt;using System;

namespace NStackExample.Data
{
    public interface IRead&amp;lt;TEntity&amp;gt; where TEntity : Entity 
    {

        TEntity GetById(Guid ID);

    }
}

namespace NStackExample.Data 
{
    public interface ISave&amp;lt;TEntity&amp;gt; where TEntity : Entity 
    {

        TEntity Save(TEntity entity);

    }
}

namespace NStackExample.Data
{
    public interface IDelete&amp;lt;TEntity&amp;gt; where TEntity:Entity 
    {

        void Delete(TEntity entity);

    }
}

using System.Collections.Generic;

namespace NStackExample.Data
{
    public interface IReadStudent : IRead&amp;lt;Student&amp;gt;
    {

        Student FindByStudentID(string StudentID);
        IEnumerable&amp;lt;Student&amp;gt; FindByName(string LikeFirstName, string LikeLastName);

    }
}

using NHibernate;

namespace NStackExample.Data
{

    public class GenericDAOImpl&amp;lt;TEntity&amp;gt; : IRead&amp;lt;TEntity&amp;gt;, ISave&amp;lt;TEntity&amp;gt; where TEntity : Entity
    {

        public GenericDAOImpl(ISession Session)
        {
            m_Session = Session;
        }

        protected readonly ISession m_Session;

        public TEntity GetByID(System.Guid ID)
        {
            if (m_Session.Transaction == null)
            {
                TEntity retval;
                using (var Tran = m_Session.BeginTransaction())
                {
                    retval = m_Session.Get&amp;lt;TEntity&amp;gt;(ID);
                    Tran.Commit();
                    return retval;
                }
            }
            else
            {
                return m_Session.Get&amp;lt;TEntity&amp;gt;(ID);
            }
        }

        public TEntity Save(TEntity Entity)
        {
            if (m_Session.Transaction == null)
            {
                using (var Tran = m_Session.BeginTransaction())
                {
                    m_Session.SaveOrUpdate(Entity);
                    Tran.Commit();
                }
            }
            else
            {
                m_Session.SaveOrUpdate(Entity);
            }
            return Entity;
        }

    }

}

using NHibernate;
using NHibernate.Criterion;
using System.Collections.Generic;
using System.Linq;

namespace NStackExample.Data
{
    public class StudentDAOImpl : GenericDAOImpl&amp;lt;Student&amp;gt;, IReadStudent
    {

        public StudentDAOImpl(ISession Session) : base(Session) { }

        public System.Collections.Generic.IEnumerable&amp;lt;Student&amp;gt; FindByName(string LikeFirstName, string LikeLastName)
        {
            ICriteria crit = m_Session.CreateCriteria&amp;lt;Student&amp;gt;()
                .Add(Expression.Like(&amp;quot;FirstName&amp;quot;, LikeFirstName))
                .Add(Expression.Like(&amp;quot;LastName&amp;quot;, LikeLastName))
                .SetMaxResults(101);
            if (m_Session.Transaction == null)
            {
                using (var Tran = m_Session.BeginTransaction())
                {
                    var RetVal = crit.List().Cast&amp;lt;Student&amp;gt;();
                    Tran.Commit();
                    return RetVal;
                }
            }
            else
            {
                return crit.List().Cast&amp;lt;Student&amp;gt;();
            }
        }

        public Student FindByStudentID(string StudentID)
        {
            var Crit = m_Session.CreateCriteria&amp;lt;Student&amp;gt;()
                .Add(Expression.Eq(&amp;quot;StudentID&amp;quot;, StudentID));
            if (m_Session.Transaction == null)
            {
                using (var Tran = m_Session.BeginTransaction())
                {
                    var RetVal = Crit.UniqueResult&amp;lt;Student&amp;gt;();
                    Tran.Commit();
                    return RetVal;
                }
            }
            else
            {
                return Crit.UniqueResult&amp;lt;Student&amp;gt;();
            }
        }


    }
}&lt;/pre&gt;

  &lt;p&gt;&lt;/p&gt;

  &lt;h3&gt;Other changes&lt;/h3&gt;

  &lt;p&gt;I’ve cleaned out the course and student DAO junk from part 7. These were just used to illustrate session-per-request. &lt;/p&gt;

  &lt;p&gt;The fluent mapping classes have been moved in to a mapping folder.&lt;/p&gt;

  &lt;p&gt;&lt;/p&gt;

  &lt;p&gt;That’s it for part 8. Don’t forget to write your tests for the queries. &lt;/p&gt;

  &lt;p&gt;Jason 
    &lt;br /&gt;- IBlog.Post(Part8) operation completed. Executing IWatchTV.Watch(Timespan.FromHours(1))&lt;/p&gt;

  &lt;p&gt;&lt;/p&gt;

  &lt;p&gt;&lt;/p&gt;

  &lt;p&gt;&lt;/p&gt;
&lt;/li&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://nhforge.org/aggbug.aspx?PostID=502" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/GArh55FJX0DiCLUba-7OxeRyo8A/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GArh55FJX0DiCLUba-7OxeRyo8A/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/GArh55FJX0DiCLUba-7OxeRyo8A/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GArh55FJX0DiCLUba-7OxeRyo8A/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/NHibernateBlog/~4/nG6mJ9D8N1M" height="1" width="1"/&gt;</description><feedburner:origLink>http://nhforge.org/blogs/nhibernate/archive/2009/09/07/part-8-daos-repositories-or-query-objects.aspx</feedburner:origLink></item></channel></rss>
