<?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>Tim Van Wassenhove &#187; NHibernate</title>
	<atom:link href="http://www.timvw.be/category/information-technology/csharp/nhibernate/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.timvw.be</link>
	<description>The journey of a thousand miles begins with one step.</description>
	<lastBuildDate>Thu, 29 Jul 2010 17:07:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Beyond the basics: IPropertyAccessor</title>
		<link>http://www.timvw.be/beyond-the-basics-ipropertyaccessor/</link>
		<comments>http://www.timvw.be/beyond-the-basics-ipropertyaccessor/#comments</comments>
		<pubDate>Sat, 27 Jun 2009 14:51:20 +0000</pubDate>
		<dc:creator>timvw</dc:creator>
				<category><![CDATA[NHibernate]]></category>

		<guid isPermaLink="false">http://www.timvw.be/?p=1091</guid>
		<description><![CDATA[Consider the following classes: an abstract Account and a concrete SavingAccount abstract class Account { int Id { get; protected set; } int CustomerId { get; protected set; } abstract AccountType Type { get; } } class SavingAccount : Account, ISavingAccount { private SavingAccount() { } public SavingAccount(int customerId) { CustomerId = customerId; } public [...]]]></description>
			<content:encoded><![CDATA[<p>Consider the following classes: an abstract Account and a concrete SavingAccount</p>

<pre class="brush: csharp;">abstract class Account
{
 int Id { get; protected set; }
 int CustomerId { get; protected set; }
 abstract AccountType Type { get; }
}

class SavingAccount : Account, ISavingAccount
{
 private SavingAccount() { }
 public SavingAccount(int customerId) {  CustomerId = customerId; }
 public override AccountType Type { get { return AccountType.SavingAccount; } }
}</pre>

<p>And this is the schema on which we want to map these classes:</p>

<img src="http://www.timvw.be/wp-content/images/accounts_schema.png" alt="screenshot of accounts schema" />

<p>We define a <a href="http://fluentnhibernate.org/">Fluent</a> NHibernate mapping as following:</p>

<pre class="brush: csharp;">public class AccountMap : ClassMap&lt;Account&gt;
{
 public AccountMap()
 {
  WithTable(&quot;Accounts&quot;);
  Id(a =&gt; a.Id).ColumnName(&quot;account_id&quot;);
  Map(a =&gt; a.CustomerId).ColumnName(&quot;customer_id&quot;);
  Map(a =&gt; a.Type).ColumnName(&quot;account_type&quot;);
  SetAttribute(&quot;lazy&quot;, &quot;false&quot;);
  
  JoinedSubClass&lt;SavingAccount&gt;(&quot;saving_account_id&quot;, MapSavingAccount);
 }

 public void MapSavingAccount(JoinedSubClassPart&lt;SavingAccount&gt; jscp)
 {
  jscp.WithTableName(&quot;SavingAccounts&quot;);
  jscp.SetAttribute(&quot;lazy&quot;, &quot;false&quot;);
 }
}</pre>

<p>As soon as we try to use this mapping we run into an &#8220;Could not find a setter for property &#8216;Type&#8217; in class &#8216;Banking.Domain.CheckingAccount&#8221; exception. A quick look with reflector teaches us there are a couple of strategies, but none of them suits our needs.</p>

<img src="http://www.timvw.be/wp-content/images/accounts_property_accessors.png" alt="screenshot of available property accessors in NHibernate assembly" />

<p>Thus we decide to implement a custom PropertyAccessor as following:</p>

<pre class="brush: csharp;">public class ReadOnlyProperty : IPropertyAccessor
{
 public bool CanAccessTroughReflectionOptimizer
 {
  get { return false; }
 }

 public IGetter GetGetter(Type theClass, string propertyName)
 {
  var basicPropertyAccessor = new BasicPropertyAccessor();
  var getter = basicPropertyAccessor.GetGetter(theClass, propertyName);
  return getter;
 }

 public ISetter GetSetter(Type theClass, string propertyName)
 {
  var setter = new NoOpSetter();
  return setter;
 }

 public class NoOpSetter : ISetter
 {
  public MethodInfo Method { get { return null; } }
  public string PropertyName { get { return null; } }
  public void Set(object target, object value) { }
 }
}</pre>

<p>And now we can instruct NHibernate to use our custom PropertyAccessor as following:</p>

<pre class="brush: csharp;">public AccountMap()
{
 ...
 Map(a =&gt; a.Type).Access.Using&lt;ReadOnlyProperty&gt;().ColumnName(&quot;account_type&quot;);
 ...
}</pre>

<p>A couple of searches later it appears that <a href="http://blog.schuager.com/2008/12/nhibernate-read-only-property-access.html">this problem had already been solved</a>, but is not available in the version of NHibernate that comes with Fluent NHibernate. Oh well, we learned something new <img src='http://www.timvw.be/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>]]></content:encoded>
			<wfw:commentRss>http://www.timvw.be/beyond-the-basics-ipropertyaccessor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
