<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>There and Back Again : NHibernate</title><link>http://blogs.msdn.com/howard_dierking/archive/tags/NHibernate/default.aspx</link><description>Tags: NHibernate</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Building NHibernate 1.2.1GA on .NET 3.5</title><link>http://blogs.msdn.com/howard_dierking/archive/2008/03/20/building-nhibernate-1-2-1ga-on-net-3-5.aspx</link><pubDate>Fri, 21 Mar 2008 00:49:14 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8327970</guid><dc:creator>hdierking</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/howard_dierking/comments/8327970.aspx</comments><wfw:commentRss>http://blogs.msdn.com/howard_dierking/commentrss.aspx?PostID=8327970</wfw:commentRss><description>&lt;p&gt;I recently reached a point where for reasons that I'm sure you can all relate to, I decided to clean my laptop and rebuild.&amp;#160; I therefore did a clean install of Vista with SP1.&amp;#160; As a quick aside, SP1 does actually seem to improve performance - particularly when starting up or closing down.&amp;#160; Anyway, after I was back up and going again, I setup &lt;a href="http://nant.sourceforge.net/"&gt;NAnt&lt;/a&gt; and then downloaded the &lt;a href="http://www.hibernate.org/343.html"&gt;NHibernate&lt;/a&gt; 1.2.1 GA source.&amp;#160; However, I ran into 2 major problems building, so I thought I would share those, along with how to work around them.&lt;/p&gt;  &lt;p&gt;Both problems can be corrected by modifying the markup in the build-common/common.xml file.&lt;/p&gt;  &lt;p&gt;The first problem had to do with the fact that the build was expecting the clover library.&amp;#160; The solution was simply to add a condition to the property set declaration.&amp;#160; I'm not going to spend any more time on this one, because the problem/solution is &lt;a href="http://forum.hibernate.org/viewtopic.php?p=2373051"&gt;documented here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The second problem is that there is no target in the build file for .NET 3.5.&amp;#160; On most machines, this isn't a big deal because you've probably upgraded framework versions incrementally, and the build file can target 2.0 with no problem.&amp;#160; Because I have a fresh OS/Framework install, I got an error saying that .NET 3.5 is not supported for my build of NHibernate.&amp;#160; This can be worked around by adding a target declaring a configuration for .NET 3.5, like so:&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;target &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;set-net-3.5-framework-configuration&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;property &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;nant.settings.currentframework&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;net-2.0&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;property &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;current.build.defines&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;${build.defines}NET,NET_2_0&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;!-- &lt;/span&gt;&lt;span style="color: green"&gt;not using SDK_v2_0 because ndoc throws an exception &lt;/span&gt;&lt;span style="color: blue"&gt;--&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;property &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;link.sdkdoc.version&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;SDK_v1_1&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;property &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;merge.targetplatform&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;v2.0&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;target&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;When you get into the config file, you'll see that all I did was create a target with 3.5 declared as a part of the target name, and then coped the body from the 2.0 target inside of my 3.5 target.&amp;#160; Initially, I had actually configured the properties to make them specific to .NET 3.5.&amp;#160; Unfortunately, I later discovered when I tried to use the compiled assemblies that many of the source files have preprocessing directives that are specific to the defines declared in the build properties.&amp;#160; For example, the ISet&amp;lt;T&amp;gt; source code is wrapped with the following directive.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;#if &lt;/span&gt;NET_2_0&lt;/pre&gt;

&lt;p&gt;Anways, after making these 2 changes, I was able to build with no problem, and NHibernate continued to work as advertised.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8327970" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Microsoft+.NET+Programming/default.aspx">Microsoft .NET Programming</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/My+Toolbox/default.aspx">My Toolbox</category></item><item><title>Last Old Blog Code Update</title><link>http://blogs.msdn.com/howard_dierking/archive/2008/03/06/last-old-blog-code-update.aspx</link><pubDate>Fri, 07 Mar 2008 10:12:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8089513</guid><dc:creator>hdierking</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/howard_dierking/comments/8089513.aspx</comments><wfw:commentRss>http://blogs.msdn.com/howard_dierking/commentrss.aspx?PostID=8089513</wfw:commentRss><description>&lt;p&gt;Ok - after posting this update, I'll consider myself caught up with regard to picking up the pieces of my old blog.&amp;nbsp; This is the updated code sample for &lt;a href="http://blogs.msdn.com/howard_dierking/archive/2007/04/23/nhibernate-custom-mapping-types.aspx" mce_href="http://blogs.msdn.com/howard_dierking/archive/2007/04/23/nhibernate-custom-mapping-types.aspx"&gt;creating custom mapping types in NHibernate&lt;/a&gt;.&amp;nbsp; The updated sample provides a loose example of implementing the &lt;a href="http://www.ksc.com/article3.htm" mce_href="http://www.ksc.com/article3.htm"&gt;type object pattern&lt;/a&gt; - a pattern where one object instance serves as the type for a set of other object instances.&amp;nbsp; Here, for the sake of simplicity and expediency, I have designed the types such that the type object is also the value container - hopefully when you look at the code, you can see it's a pretty simple process to go a step farther and implement the full pattern.&lt;/p&gt;  &lt;p&gt;Anyway, similar to &lt;a href="http://blogs.msdn.com/howard_dierking/archive/2008/03/01/old-tdd-demo-blog-digest-and-code.aspx" mce_href="http://blogs.msdn.com/howard_dierking/archive/2008/03/01/old-tdd-demo-blog-digest-and-code.aspx"&gt;my last post&lt;/a&gt;, I've updated the code to use the &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=73818" mce_href="http://sourceforge.net/project/showfiles.php?group_id=73818"&gt;latest version of NHibernate&lt;/a&gt;, and I've added in some &lt;a href="http://msdn2.microsoft.com/en-us/magazine/cc163400.aspx" mce_href="http://msdn2.microsoft.com/en-us/magazine/cc163400.aspx"&gt;LINQ goodness&lt;/a&gt;.&amp;nbsp; And of course, all demoware disclaimers apply.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8089513" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/howard_dierking/attachment/8089513.ashx" length="2219803" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Microsoft+.NET+Programming/default.aspx">Microsoft .NET Programming</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Test+Driven+Development/default.aspx">Test Driven Development</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/NHibernate/default.aspx">NHibernate</category></item><item><title>Old TDD Demo Blog - Digest and Code</title><link>http://blogs.msdn.com/howard_dierking/archive/2008/03/01/old-tdd-demo-blog-digest-and-code.aspx</link><pubDate>Sun, 02 Mar 2008 10:24:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7986666</guid><dc:creator>hdierking</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/howard_dierking/comments/7986666.aspx</comments><wfw:commentRss>http://blogs.msdn.com/howard_dierking/commentrss.aspx?PostID=7986666</wfw:commentRss><description>&lt;p&gt;Several of you have emailed me over the past several months asking if I had a copy of the blog text and/or code that I had mentioned in a &lt;a href="http://blogs.msdn.com/howard_dierking/archive/2006/10/29/adventures-in-tdd-ddd-and-nhibernate-from-a-past-life.aspx" mce_href="http://blogs.msdn.com/howard_dierking/archive/2006/10/29/adventures-in-tdd-ddd-and-nhibernate-from-a-past-life.aspx"&gt;much earlier blog entry&lt;/a&gt;.&amp;nbsp; As it turns out, a good friend of mine found some old archived versions of the site on an Internet cache and set them over to me.&amp;nbsp; Therefore, I have taken the web pages and compiled them into an XPS document so that you can see the thought progression that went along with building a small application, TDD style.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;Additionally, I've updated the code samples a bit.&amp;nbsp; Specifically, I've upgraded the version of &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=73818" mce_href="http://sourceforge.net/project/showfiles.php?group_id=73818"&gt;NHibernate to 1.2.1.GA&lt;/a&gt; - and as such, dropped the use of &lt;a href="http://www.ayende.com/projects/nhibernate-query-analyzer/generics.aspx" mce_href="http://www.ayende.com/projects/nhibernate-query-analyzer/generics.aspx"&gt;Ayende's NHibernate Generics library&lt;/a&gt;.&amp;nbsp; Also, as I was going through my NHibernate mappings, I realized that I had been pretty lazy with regard to semantic accuracy for collection types - I had pretty much completely used &amp;lt;bag&amp;gt; mappings instead &amp;lt;set&amp;gt; mappings for unordered collections so that I could use IList&amp;lt;T&amp;gt;.&amp;nbsp; Therefore, I cleaned that up a bit.&amp;nbsp; Other than that, the only other thing that I did was update some of the looping and conditional code to use LINQ.&lt;/p&gt;  &lt;p&gt;Finally, let me emphatically throw out the "Demoware Disclaimer" - The point of the blog and the code samples was to illustrate the thought process and corresponding code behind using TDD to &lt;b&gt;design &lt;/b&gt;a domain model.&amp;nbsp; As a result, everything else in the code is the simplest thing that could be implemented to support the overall goal - and nothing more.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7986666" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/howard_dierking/attachment/7986666.ashx" length="2480294" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Microsoft+.NET+Programming/default.aspx">Microsoft .NET Programming</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Test+Driven+Development/default.aspx">Test Driven Development</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Agile/default.aspx">Agile</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/NHibernate/default.aspx">NHibernate</category></item><item><title>NHibernate Custom Mapping Types</title><link>http://blogs.msdn.com/howard_dierking/archive/2007/04/23/nhibernate-custom-mapping-types.aspx</link><pubDate>Tue, 24 Apr 2007 05:36:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2254247</guid><dc:creator>hdierking</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/howard_dierking/comments/2254247.aspx</comments><wfw:commentRss>http://blogs.msdn.com/howard_dierking/commentrss.aspx?PostID=2254247</wfw:commentRss><description>&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;(originally posted to &lt;A href="http://blogs.sarkhouston.com/hdierking/" target=_blank mce_href="http://blogs.sarkhouston.com/hdierking/"&gt;Absolute Opinion&lt;/A&gt; on June 14, 2006) 
&lt;P&gt;As you should know by now, NHibernate is an object-relational mapping (ORM) tool that uses XML metadata files to marshal data between an object-oriented domain model and a relational database. Now, in the majority of use cases, the default support provided by NHibernate will be sufficient for saving and fetching your domain objects. However, there are cases where additional capabilities are required. Fortunately, NHibernate provides lots of extension points. I’m going to discuss 2 scenarios in this article – both of which take advantage of creating custom NHibernate mapping types. 
&lt;P&gt;&lt;B&gt;Scenario 1:&lt;/B&gt; 
&lt;P&gt;You have an implementation of the &lt;A href="http://www.ksc.com/article3.htm" mce_href="http://www.ksc.com/article3.htm"&gt;Type Object Pattern&lt;/A&gt;. Simply put, you have a class to represent the type of an object, and then a class the references your type object. The static model looks like the following. 
&lt;P&gt;&lt;IMG src="http://intranet.sarkhouston.com/intranet/code/Code%20Samples/hdierking_blog/TypeObjectStaticDiagram.gif" mce_src="http://intranet.sarkhouston.com/intranet/code/Code%20Samples/hdierking_blog/TypeObjectStaticDiagram.gif"&gt; 
&lt;P&gt;Now, let’s take this a step further and say that your type class takes a pretty large amount of time to construct and initialize. Therefore, you decide to implement a &lt;A href="http://www.dofactory.com/Patterns/PatternFlyweight.aspx" mce_href="http://www.dofactory.com/Patterns/PatternFlyweight.aspx"&gt;flyweight factory&lt;/A&gt; in order to minimize the performance impact on your application in terms of the number of type class instances that must be constructed. Fantastic! Now, let’s look at the ramifications on persistence. 
&lt;P&gt;From the object persistence perspective, the problem you are now facing is that you do not want to persist the object state for your TypeClass instance (since you are trying to control the number of instances for that class). However, you do want to persist enough information about the TypeClass instance so that when you load an instance of ActualClass from the database, you can get the correct TypeClass instance from the flyweight factory and apply it to your reconstructed ActualClass instance. 
&lt;P&gt;Now in a world without NHibernate (oh what a sad world!), we would create a data access class for ActualClass and add methods for setting and fetching ActualClass instances. Since the TypeClass reference exists outside of the database scope, we would add the association in the data access class. For example, your data access class may have code that looks like the following.&amp;nbsp;&amp;nbsp; 
&lt;DIV class=csharpcode&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; ActualClassRepository {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;  &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Save(ActualClass actualClass) {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;    IDbCommand cmd = &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;    IDbDataParameter param;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   5:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   6:  &lt;/SPAN&gt;    &lt;SPAN class=rem&gt;//build the sql command and parameters...&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   7:  &lt;/SPAN&gt;    param = cmd.CreateParameter();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   8:  &lt;/SPAN&gt;    param.ParameterName = &lt;SPAN class=str&gt;"@typeClass"&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   9:  &lt;/SPAN&gt;    param.DbType = DbType.String;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  10:  &lt;/SPAN&gt;    param.Value = actualClass.Type.Name;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  11:  &lt;/SPAN&gt;  }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  12:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  13:  &lt;/SPAN&gt;  &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; ActualClass Get(&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; id) {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  14:  &lt;/SPAN&gt;    IDataReader rdr = &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  15:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  16:  &lt;/SPAN&gt;    &lt;SPAN class=rem&gt;//build the sql command to and get a data reader...&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  17:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (rdr.Read()) {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  18:  &lt;/SPAN&gt;      ActualClass ret = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; ActualClass();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  19:  &lt;/SPAN&gt;      ret.Data = rdr.GetString(0);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  20:  &lt;/SPAN&gt;      TypeClassFactory factory = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; TypeClassFactory();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  21:  &lt;/SPAN&gt;      ret.Type = factory.GetTypeClass(rdr.GetString(1));&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  22:  &lt;/SPAN&gt;    }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  23:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  24:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  25:  &lt;/SPAN&gt;  }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  26:  &lt;/SPAN&gt;}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/STYLE&gt;

&lt;STYLE type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/STYLE&gt;

&lt;P&gt;If you pay attention to the code shown in bold for both the get and set methods, you can see how your data access class might handle the setting and fetching of an object and its associated type object. When saving the ActualClass object, the data access object saves the name of the associated TypeClass object to the database. When the ActualClass object is restored from the database, the name of the TypeClass is retrieved and passed to our flyweight factory where the object instance can be acquired and set on the ActualClass object being built. 
&lt;P&gt;Now, this works fine in very simple cases like the one mentioned above. However, most object models have many more complex sets of associations. It is in cases like this where NHibernate reveals a great deal of strength – and it would be advantageous to be able to use NHibernate to solve our type object problem. 
&lt;P&gt;Enter the custom mapping type. 
&lt;P&gt;In NHibernate, a custom mapping type is a class that derives from either the IUserType or ICompositeUserType interfaces. These interfaces contain several methods that must be implemented, but for our purposes here, we’re going to focus on 2 of them. Consider the following.&amp;nbsp;&amp;nbsp; 
&lt;DIV class=csharpcode&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; TypeClassUserType : IUserType&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;{&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;  ...&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   5:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   6:  &lt;/SPAN&gt;  &lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; IUserType.NullSafeGet(IDataReader rs, &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   7:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;[] names, &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   8:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; owner) {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   9:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  10:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; name = NHibernateUtil.String.NullSafeGet(rs, &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  11:  &lt;/SPAN&gt;      names[0]) &lt;SPAN class=kwrd&gt;as&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  12:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  13:  &lt;/SPAN&gt;    TypeClassFactory factory = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; TypeClassFactory();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  14:  &lt;/SPAN&gt;    TypeClass typeobj = factory.GetTypeClass(name);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  15:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; typeobj;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  16:  &lt;/SPAN&gt;  }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  17:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  18:  &lt;/SPAN&gt;  &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; IUserType.NullSafeSet(IDbCommand cmd, &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  19:  &lt;/SPAN&gt;    &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;SPAN class=lnum&gt;  20:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; index) {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  21:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  22:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; name = ((TypeClass)&lt;SPAN class=kwrd&gt;value&lt;/SPAN&gt;).Name;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  23:  &lt;/SPAN&gt;    NHibernateUtil.String.NullSafeSet(cmd, name, index);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  24:  &lt;/SPAN&gt;  }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  25:  &lt;/SPAN&gt;}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/STYLE&gt;

&lt;P&gt;Having created this class, I can now explicitly map the association between ActualClass and TypeClass as a simple property on the ActualClass mapping.&lt;PRE class=csharpcode&gt;&amp;lt;property
  name=&lt;SPAN class=str&gt;"Type"&lt;/SPAN&gt;
  column=&lt;SPAN class=str&gt;"TypeName"&lt;/SPAN&gt;
  type=&lt;SPAN class=str&gt;"Samples.NHibernate.DataAccess.TypeClassUserType, 
    Samples.NHibernate.DataAccess"&lt;/SPAN&gt; /&amp;gt;&lt;/PRE&gt;
&lt;STYLE type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/STYLE&gt;

&lt;P&gt;As NHibernate is in the process of saving an instance of ActualType, it will load and create a new instance of TypeClassUserType and call the NullSafeSet method. As you can see from the method body, I am simply extracting the name from the mapped property (passed in as the value parameter) and setting the extracted name as the value of the parameter to be set in the database. The net result is that although the Type property of ActualClass is TypeClass in the domain model, only the Name property of the TypeClass object gets stored in the database. The converse is also true. When NHibernate is loading an instance of ActualType from the database and the finds a property of my custom mapping type, it loads my custom type and calls the NullSafeGet method. As you can see, my method gets the name from the returned data, calls my flyweight factory to get the correct instance of TypeClass, and then actually returns that instance. The type resolution process happens transparently to my data access classes (and even to NHibernate itself for that matter). 
&lt;P&gt;&lt;B&gt;Scenario 2:&lt;/B&gt; 
&lt;P&gt;As a part of your object model, you have a standard IDictionary implementation (Oh my goodness – untyped collections!!! Yea – it still happens sometimes!) that looks as follows.&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; IDictionary _values = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; Hashtable();&lt;/PRE&gt;
&lt;P&gt;Now, here’s the basic problem with this implementation when persisting to a database. By design, this data structure can contain – well – anything. So how do you persist it to the database in a meaningful way? One technique that can be used is to store the value as a string in one column and store the type identifier as a string in a different column. The problem here is that many times (especially when you think about it from the database point of view) you end up with a clunky object model because there is no real reason to store the type as an additional piece of data. Fundamentally, the database requires 2 pieces of information to make sense of 1 piece of domain model information (value + type). It would be really great if we could hide this splitting and merging of data in the mapping layer… 
&lt;P&gt;…and we can – using a composite custom mapping type. Take a look at the following. 
&lt;DIV class=csharpcode&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; Object2StringUserType : ICompositeUserType&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;{&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;  ...&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   5:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   6:  &lt;/SPAN&gt;  &lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; ICompositeUserType.NullSafeGet(IDataReader dr, &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   7:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;[] names, &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   8:  &lt;/SPAN&gt;    ISessionImplementor session, &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   9:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; owner) {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  10:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  11:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; val = (&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;) NHibernateUtil.String.NullSafeGet(dr, &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  12:  &lt;/SPAN&gt;      names[0], &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  13:  &lt;/SPAN&gt;      session, &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  14:  &lt;/SPAN&gt;      owner);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  15:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  16:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; valTypeString = &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  17:  &lt;/SPAN&gt;      (&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;) NHibernateUtil.String.NullSafeGet(dr, &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  18:  &lt;/SPAN&gt;        names[1], &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  19:  &lt;/SPAN&gt;        session, &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  20:  &lt;/SPAN&gt;        owner);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  21:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  22:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (val == &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt; || valTypeString == &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  23:  &lt;/SPAN&gt;      &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  24:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  25:  &lt;/SPAN&gt;    Type valType = Type.GetType(valTypeString);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  26:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; TypeDescriptor.GetConverter(valType).ConvertFrom(val);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  27:  &lt;/SPAN&gt;  }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  28:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  29:  &lt;/SPAN&gt;  &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; ICompositeUserType.NullSafeSet(IDbCommand cmd, &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  30:  &lt;/SPAN&gt;    &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;SPAN class=lnum&gt;  31:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; index, &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  32:  &lt;/SPAN&gt;    ISessionImplementor session) {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  33:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  34:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; valString = TypeDescriptor.GetConverter(&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  35:  &lt;/SPAN&gt;      &lt;SPAN class=kwrd&gt;value&lt;/SPAN&gt;.GetType()).ConvertToString(&lt;SPAN class=kwrd&gt;value&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  36:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  37:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; valTypeString = &lt;SPAN class=kwrd&gt;value&lt;/SPAN&gt;.GetType().AssemblyQualifiedName;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  38:  &lt;/SPAN&gt;    NHibernateUtil.String.NullSafeSet(cmd, valString, index, session);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  39:  &lt;/SPAN&gt;    NHibernateUtil.String.NullSafeSet(cmd, &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  40:  &lt;/SPAN&gt;      valTypeString, index + 1, session);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  41:  &lt;/SPAN&gt;  }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  42:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  43:  &lt;/SPAN&gt;  &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;[] ICompositeUserType.PropertyNames {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  44:  &lt;/SPAN&gt;    get { &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;[] {&lt;SPAN class=str&gt;"val"&lt;/SPAN&gt;, &lt;SPAN class=str&gt;"valType"&lt;/SPAN&gt;}; }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  45:  &lt;/SPAN&gt;  }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  46:  &lt;/SPAN&gt;}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/STYLE&gt;

&lt;STYLE type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/STYLE&gt;

&lt;STYLE type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/STYLE&gt;

&lt;STYLE type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/STYLE&gt;

&lt;P&gt;As you can see, this interface fragment looks similar to that of our regular custom mapping type. However, it has several additional members which allow the custom type to actually map a given domain model value onto multiple database columns. In this example, I have used the type to split the value of my IDictionary object over 2 columns in my database table: Value and ValueType. When my dictionary is persisted, my mapping type converts the dictionary value to a string and then persists that value along with the fully qualified name of the value’s original type to 2 columns in the database. Those columns are identified in NHibernate mapping file and mapped to property names (in this case val and valType) based on the order in which they appear in the mapping file. The NHibernate mapping XML looks as follows. &lt;PRE class=csharpcode&gt;&amp;lt;map name=&lt;SPAN class=str&gt;"_values"&lt;/SPAN&gt; access=&lt;SPAN class=str&gt;"field"&lt;/SPAN&gt; table=&lt;SPAN class=str&gt;"Values"&lt;/SPAN&gt;&amp;gt; 
  &amp;lt;key column=&lt;SPAN class=str&gt;"ID_Parent"&lt;/SPAN&gt;&amp;gt;&amp;lt;/key&amp;gt; 
  &amp;lt;index column=&lt;SPAN class=str&gt;"Key"&lt;/SPAN&gt; type=&lt;SPAN class=str&gt;"String"&lt;/SPAN&gt;&amp;gt;&amp;lt;/&amp;lt; SPAN&amp;gt;index&amp;gt; 
  &amp;lt;element type=&lt;SPAN class=str&gt;"Samples.NHibernate.DataAccess.Object2StringUserType, 
       Samples.NHibernate.DataAccess"&lt;/SPAN&gt;&amp;gt; 
    &amp;lt;column name=&lt;SPAN class=str&gt;"Value"&lt;/SPAN&gt; /&amp;gt; 
    &amp;lt;column name=&lt;SPAN class=str&gt;"ValueType"&lt;/SPAN&gt;/&amp;gt; 
  &amp;lt;/element&amp;gt; 
&amp;lt;/map&amp;gt; &lt;/PRE&gt;
&lt;STYLE type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/STYLE&gt;

&lt;STYLE type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/STYLE&gt;

&lt;P&gt;Again, all of this happens behind the scenes as NHibernate is setting and fetching your objects from the database. All you know is that for any type that you put into the your dictionary, you can expect the same type to be in the dictionary for that item, even after saving and loading it from the database. 
&lt;P&gt;In conclusion, I hope that this has illustrated the flexibility that can be found within NHibernate as it relates to some more advanced mapping scenarios. If you have any questions or ideas for custom mapping types, please share!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2254247" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Microsoft+.NET+Programming/default.aspx">Microsoft .NET Programming</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Agile/default.aspx">Agile</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/NHibernate/default.aspx">NHibernate</category></item><item><title>Designing a Domain-Driven Data Access Layer</title><link>http://blogs.msdn.com/howard_dierking/archive/2007/04/23/designing-a-domain-driven-data-access-layer.aspx</link><pubDate>Tue, 24 Apr 2007 05:35:57 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2254244</guid><dc:creator>hdierking</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/howard_dierking/comments/2254244.aspx</comments><wfw:commentRss>http://blogs.msdn.com/howard_dierking/commentrss.aspx?PostID=2254244</wfw:commentRss><description>&lt;p&gt;(originally posted to &lt;a href="http://blogs.sarkhouston.com/hdierking/" target="_blank"&gt;Absolute Opinion&lt;/a&gt; on June 4, 2006)  &lt;p&gt;I had started writing a post about best practices for using the different NHibernate collection mapping types when it dawned on me that I may be assuming too much in thinking that we all look at data access layers in the same way. In fact, I think that it is fair to say that most folks who came through the ADO school of data access were trained to think of the data access layer as little more than a set of helper classes used to connect “business objects” to SQL Server stored procedures.  &lt;p&gt;Now, for those of you who still view the data access layer in the way that I described above, this article is not to convince you that you are wrong (even though you are). However, I think it may be fair to say that you may have trouble fitting what I’m going to describe into your way of thinking.  &lt;p&gt;So let’s start with a few very basic goals for a data access layer (DAL).  &lt;ul&gt; &lt;li&gt;The DAL should completely hide the underlying data access technology, whether it be an ORM tool like NHibernate, hand-generated inline SQL, calls to stored procedures, or anything else.  &lt;li&gt;The DAL should not place any significant constraints on the design of the domain model.  &lt;li&gt;The entire layer should be replaceable with minimal impact (or minimal risk for you PM folks).&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Now, all of the aforementioned goals can be summarized with one word: decoupling. This is a great word – it’s a word that we keep hearing over and over again with every architecture talk and every article. In fact, didn’t the introduction of component programming give us decoupling without any effort on our parts?  &lt;p&gt;In case you were wondering about that last one, the short answer is – no.  &lt;p&gt;So what should a decoupled DAL look like? In .NET programming terms, the answer lies in the references. Given our stated DAL goals, we need to be able to pull out our entire DAL and replace it with another (say one that persists our objects to and from the file system rather than a RDBMS) without causing any impact on the rest of the system. We therefore can’t have our business layer (henceforth called domain model) having any knowledge that a DAL even exists. This is due to the fact that our domain model is designed to be the very core of our system. The objects contained within the domain model form the basic language that our software system uses to describe a real world problem. Put another way, our domain model is (or, should be) a neutral layer in terms of technology concerns. The last thing that we should want to do is create a dependency on a layer whose sole focus is a technology-specific concern (persistence).  &lt;p&gt;So, getting back to observing decoupling through references, what can we deduce from my tangential diatribe above? Firstly, the DAL assembly should hold a reference to the domain model assembly – the domain model assembly should not reference the DAL in any way. Secondly, all other assemblies that need to interact with a persistent store to get and set domain objects will hold a reference to both the domain model assembly and to the DAL assembly. To pull from the SARK Classic project, such a relationship looks as follows:  &lt;p&gt;&lt;img src="http://intranet.sarkhouston.com/intranet/code/Code%20Samples/tdd_blog/LayeringArchitecture.gif" border="0"&gt;  &lt;p&gt;Now that we have an architectural view of what the DAL should look like, what should it look like at the code level? Firstly, DAL classes should be defined not in terms of “1 DAL class per 1 domain model class” but rather in terms of domain model &lt;i&gt;aggregates&lt;/i&gt;. The term aggregate was defined by Eric Evans in his book &lt;i&gt;&lt;a href="http://www.amazon.com/gp/product/0321125215/sr=8-1/qid=1149482938/ref=pd_bbs_1/002-1535884-2139211?%5Fencoding=UTF8"&gt;Domain Driven Design&lt;/a&gt;&lt;/i&gt; as follows.  &lt;p&gt;“An AGGREGATE is a cluster of associated objects that we treat as a unit for the purpose of data changes. Each AGGREGATE has a root and a boundary. The boundary defines what is inside the AGGREGATE. The root is a single, specific ENTITY contained in the AGGREGATE.”  &lt;p&gt;So you may be wondering why the terms “aggregate” and “entity” are typed in caps – well, me too – that’s just the way the book was written.  &lt;p&gt;Let’s apply that definition to the &lt;a href="http://blogs.sarkhouston.com/tdd/"&gt;SARK Classic sample project&lt;/a&gt;. A golf course has a specified number of holes – and each hole has a par value. However, the unit of change from the data perspective is always the course – i.e. – there is never a time when you would access a specific hole directly – you would always access a hole through the course. Therefore, we can say that the Course Aggregate consists of 2 classes: Course and Hole. That is the aggregate boundary. Additionally, Course is the aggregate root. In support of the aggregate boundary, DAL objects should be defined for aggregates – not specifically for domain objects.  &lt;p&gt;Once you have defined aggregate boundaries, you will hopefully find that persistence concerns can be dealt with at a more coarsely granular scope. Dealing with aggregates rather than objects may also help reduce decoupling even within the domain model. I’ve seen that many domain models have unnecessary associations between objects simply for the purpose of pulling down the entire object graph during persistence. In thinking of persistence in terms of aggregates rather than domain objects, you may also see opportunities to get rid of some of these associations and instead simply create additional query methods on the DAL object for the associated aggregate. This idea is also discussed in Eric Evans’ book, so for additional research on the topic of aggregates, it is a must.  &lt;p&gt;Now, when talking about DALs that are written in terms of a domain model rather than a technology like DataSets, critics typically raise a very good point: Why is this design technique worth losing all of the wonderful support that Visual Studio provides for RAD development? In short, it’s not. A colleague once said something very profound – it was something I was already doing, but I like the way that he said it, so I’m going to attempt to quote him. He said, “Render unto the DAL that which is the DAL’s – render unto the DataGrid that which is the DataGrid’s”. Ok, he was talking about NHibernate – and I’m generalizing a bit more – I’m certain that he will forgive me. If you’re building an ASP.NET application using a GridView, you should use the data source providers in the .NET framework to populate that GridView. Your DAL should not be concerned with dealing with tabular data (especially now that the data source providers are in the .NET Framework). Your DAL is concerned with getting and setting domain objects. See? You can have your cake and eat it too!  &lt;p&gt;Finally, let’s spend a few minutes dealing with DAL design as it relates to NHibernate. Again, I want to quickly reiterate that the DAL design style that we’ve been discussing in no way relies on NHibernate. However, there are some major benefits to using NHibernate inside of your DAL.  &lt;ul&gt; &lt;li&gt;Reflection based mapping allows complete encapsulation of object state, as it can reflect over private members.  &lt;li&gt;NHibernate keeps track of the mapped id of an object and can determine whether it is a new object (known as a transient entity) or whether it is an existing persistent object. The NHibernate API then allows you to simply call a method “SaveOrUpdate(object)” – and NHibernate will determine the type of query that needs to be run.  &lt;li&gt;NHibernate keeps track of the dirty state of object members.  &lt;li&gt;For object graphs where there are several associations, NHibernate can be optimized to use outer joining so that only one query needs to be run rather than running a query for the aggregate root’s data, then running subsequent queries for the other members of the aggregate.  &lt;li&gt;Caching anyone?  &lt;li&gt;NHibernate supports multiple RDBMSs right out of the box (or zip file)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;These are just some of the many benefits to using NHibernate as your data access technology. Over the next couple weeks we will dive into some of the specifics of using NHibernate. However, like I said at the beginning, I want to make sure that we’re all on the same page architecturally before getting into the details.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2254244" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Microsoft+.NET+Programming/default.aspx">Microsoft .NET Programming</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Agile/default.aspx">Agile</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/NHibernate/default.aspx">NHibernate</category></item></channel></rss>