<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jan Limpens &#187; .NET</title>
	<atom:link href="http://blog.limpens.com/tag/net/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.limpens.com</link>
	<description>ill/dev/com</description>
	<lastBuildDate>Tue, 01 Sep 2009 13:46:08 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Handling Collections with NHibernate</title>
		<link>http://blog.limpens.com/2008/08/31/handling-collections-with-nhibernate/</link>
		<comments>http://blog.limpens.com/2008/08/31/handling-collections-with-nhibernate/#comments</comments>
		<pubDate>Sun, 31 Aug 2008 14:17:43 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[NHibernate]]></category>

		<guid isPermaLink="false">http://blog.limpens.com/?p=7</guid>
		<description><![CDATA[When business entities hold some collection and you read the NHibernate manual on how to handle this, most parts of the book (not all) will either tell you to expose this either as an IList (more pragmatic) or as an ISet (more beautiful, performant, failsafe, etc.).
I am under the impression that it generally is a [...]]]></description>
			<content:encoded><![CDATA[<p>When business entities hold some collection and you read the NHibernate manual on how to handle this, most parts of the book (not all) will either tell you to expose this either as an IList (more pragmatic) or as an ISet (more beautiful, performant, failsafe, etc.).</p>
<p>I am under the impression that it generally is a bad idea to expose any type of collection that way. Why?</p>
<p>(I go with IList here, but same applies to any other collection)</p>
<p>case 1)<br />
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre class="csharpcode">
<span class="kwrd">class</span> Bar {
    <span class="kwrd">public</span> Foo Parent {get;set;}
}

<span class="kwrd">class</span> Foo {
    <span class="kwrd">public</span> IList&lt;Bar&gt; Bars {get; set;}
}</pre>
<p>Now you are completely exposed. Anyone who has to handle this code, must be conscious of any side effects this may have. For instance, if you have a bidirectional relation to handle you must code like that, or you&#8217;ll get an error:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre class="csharpcode">
var bar = <span class="kwrd">new</span> Bar();
var foo = <span class="kwrd">new</span> Foo();
bar.Foo = foo;
foo.Bars = <span class="kwrd">new</span> List&lt;Bar&gt;();
foo.Bars.Add(bar);</pre>
<p>Quite a bit of code that will repeat over and over in your app. My verdict: avoid this! Many people go with something slightly better:</p>
<p>2) Shielded and somewhat correct<br />
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre class="csharpcode">
<span class="kwrd">class</span> Foo {
    IList bars&lt;Bar&gt; = <span class="kwrd">new</span> List&lt;Bar&gt;();

    <span class="kwrd">public</span> IList&lt;Bar&gt; Bars {
        get { <span class="kwrd">return</span> <span class="kwrd">new</span> List&lt;Bar&gt;(bars).AsReadonly; }
        <span class="kwrd">private</span> set { bars = <span class="kwrd">value</span>; }
    }

    <span class="kwrd">public</span> <span class="kwrd">void</span> AddBar(Bar bar){
        <span class="rem">// set whatever is necessary to keep consistence and let the user forget</span>
        <span class="rem">// about persistence details like bidirectionality</span>
    }
}</pre>
<p>If you unit test this, your tests will be green and you will be shielded against mistakes. You can forget the inner workings and everything will be fine. That is, unless you want to load this collection lazily (and receive lots of performance benefits). I actually already forgot what the concrete problem was, but it seems, that NHibernate inspects, what Bars delivered and tries to give the same back using the private setter. It got a ReadOnlyCollection, so it tries to set one. And this fails somehow. (I&#8217;ll try to come up with the original error). So you either return bars directly and leave two possible ways to access it, one that works, and one that sometimes works. Horror. Or. you go, by what I do right now.</p>
<p>3) Shielded<br />
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre class="csharpcode">
<span class="kwrd">class</span> Foo {
    <span class="kwrd">private</span> ISet&lt;Bar&gt; barSet;

    <span class="kwrd">public</span> ReadOnlyCollection&lt;Bar&gt; Bars {
        get {<span class="kwrd">return</span> <span class="kwrd">new</span> List&lt;Bar&gt;(barSet); }
    }

    <span class="kwrd">public</span> <span class="kwrd">void</span> AddBar()Bar bar {
        <span class="rem">// add a bar</span>
    }
}
</pre>
<p>This</p>
<ol>
<li>uses the NHibernatewise better performing Set, that most possibly also represents much better your idea of what should be returned.</li>
<li>returns a shielded IList, that has the foreach semantics you were looking for (ISet has not)</li>
<li>Shields you from future mistakes</li>
</ol>
<p>Mind: You map against bars using a &lt;set/&gt; tag. This is a very basic pattern, but I thought, if you are new to it, it might give you a better start. I did not find this documented anywhere.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.limpens.com/2008/08/31/handling-collections-with-nhibernate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
