<?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>Elegant Code &#187; Fluent NHibernate;State Pattern;Enumeration</title>
	<atom:link href="http://elegantcode.com/tag/fluent-nhibernatestate-patternenumeration/feed/" rel="self" type="application/rss+xml" />
	<link>http://elegantcode.com</link>
	<description></description>
	<lastBuildDate>Tue, 15 May 2012 10:00:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>State Pattern, Enumeration Class and Fluent NHibernate (Oh my!)</title>
	<atom:link href="http://elegantcode.com/tag/fluent-nhibernatestate-patternenumeration/feed/" rel="self" type="application/rss+xml" />
	<link>http://elegantcode.com</link>
	<description></description>
	<lastBuildDate>Tue, 15 May 2012 10:00:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Elegant Code &#187; Fluent NHibernate;State Pattern;Enumeration</title>
	<atom:link href="http://elegantcode.com/tag/fluent-nhibernatestate-patternenumeration/feed/" rel="self" type="application/rss+xml" />
	<link>http://elegantcode.com</link>
	<description></description>
	<lastBuildDate>Tue, 15 May 2012 10:00:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>State Pattern, Enumeration Class and Fluent NHibernate (Oh my!)</title>
		<link>http://elegantcode.com/2009/11/01/state-pattern-enumeration-class-and-fluent-nhibernate-oh-my/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=state-pattern-enumeration-class-and-fluent-nhibernate-oh-my</link>
		<comments>http://elegantcode.com/2009/11/01/state-pattern-enumeration-class-and-fluent-nhibernate-oh-my/#comments</comments>
		<pubDate>Mon, 02 Nov 2009 04:20:10 +0000</pubDate>
		<dc:creator>Richard Cirerol</dc:creator>
				<category><![CDATA[.Net 3.5]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Fluent NHibernate;State Pattern;Enumeration]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2009/11/01/state-pattern-enumeration-class-and-fluent-nhibernate-oh-my/</guid>
		<description><![CDATA[Recently, I needed to change a basic enumeration into a full-fledged state pattern. After getting all my domain classes updated, I began reviewing the persistence layer. And I hit a wall.  I wasn’t sure how I wanted to update my Fluent NHibernate convention to persist the current state.]]></description>
			<content:encoded><![CDATA[Recently, I needed to change a basic enumeration into a full-fledged state pattern. After getting all my domain classes updated, I began reviewing the persistence layer. And I hit a wall.  I wasn’t sure how I wanted to update my Fluent NHibernate convention to persist the current state.

My original classes were similar to this:
<pre class="brush: csharp;">public class MyProgress{ 
   public virtual Guid Id { get; set; }
   ...
   ... 
   public virtual MyStatus Status { get; private set; }
}

public enum MyStatus{ 
   New, 
   InProgress, 
   Completed, 
   Canceled, 
   Failed
}
</pre>
My new state pattern was similar to this:
<pre class="brush: csharp;">
public abstract class MyStatus
{
    public static readonly MyStatus New = new NewStatus();
    public static readonly MyStatus InProgress = new InProgressStatus();
    ...
}

public class NewStatus: MyStatus
{
    public override void Start(MyProgress progress)
    {
        progress.SetStatus(InProgress);
    }
    public override void Cancel(MyProgress progress)
    {
        progress.SetStatus(Cancelled);
    }
    public override void Fail(MyProgress progress)
    {
            progress.SetStatus(Failed);
    }
}
...
</pre>
Here is the problem… My enumeration was persisted as an integer field on the record. Now that I had a state pattern, how should I save my state? I googled the problem and found <a href="http://www.lostechies.com/blogs/derickbailey/archive/2008/11/26/mapping-a-state-pattern-with-nhibernate.aspx" target="_blank">Derick Bailey’s article</a> on the state pattern and Fluent NHibernate. Derick’s pattern works well, but I felt that creating a lookup table in my database just so I can persist a value in another table was not the path I wanted to traverse – I wasn’t persisting an entity, I was persisting a state value on an entity. Not finding any more love from Google, I asked around and was advised to contact fellow Elegant Coder and <a href="http://guild3.com" target="_blank">Guild3</a> member, <a href="http://elegantcode.com/author/jgrundy/" target="_blank">Jason Grundy</a>. Here is Jason’s advice:
<blockquote>"I've recently changed from using Enums to an approach outlined by Jimmy Bogard <a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/08/12/enumeration-classes.aspx">here</a>.  In the Entity I would do something like this:
<pre class="brush: csharp;">
protected int _orderStatusId;
public virtual OrderStatus OrderStatus
{
    get { return Enumeration.FromValue&lt;OrderStatus&gt;(_orderStatusId); }
    set { _orderStatusId = value.Value; }
}
</pre>
Then in Fluent NH you can simply map to the protected member."</blockquote>
I decided to pursue Jason’s advice.  The result is my database tables did not need to change at all. Here is some snippets of the updated classes:
<pre class="brush: csharp;">
public class MyProgress
{
     public virtual Guid Id {get;set;}
     ...
     protected int _status;
     public virtual MyStatus
     {
         get{ return Enumeration.FromValue&lt;MyStatus&gt;(_status); }
         set{ _status = value.Value; }
     }
     ...
}
 
public class MyStatus : Enumeration
{
     public static MyStatus New = new NewStatus();
     ...
 
     private class NewStatus : MyStatus
    {
         public NewStatus() : base (0,"New"){}

         public override void Start(MyProgress progress)
         {
             progress.SetStatus(InProgress);
         }
    }
     ...
</pre>
Notice that the MyStatus class is no longer abstract.  However, the subclasses are all private nested classes, each with a value and a display name.  I set each subclass value to match the enumeration value it replaced.  I did not need to convert my existing data to a new schema.

And here is the Fluent NHibernate override:
<pre class="brush: csharp;">
public class MyProgressOverride : IAutoMappingOverride&lt;MyProgress&gt;
{
    public void Override(AutoMapping&lt;MyProgress&gt; mapping)   
    {
        mapping.Map(x =&gt; x.Status)
            .CustomType(typeof(int))
            .Access.CamelCaseField(Prefix.Underscore);
    }
}
</pre>
As you can see, we use convention-based automapping with overrides, but this same map could be used in a standard class map.

Thanks to Jimmy, Derick, and Jason for the inspiration and assistance!

<script type="text/javascript"> 
var cirerolGaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + cirerolGaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script> 
<script type="text/javascript"> 
var cirerolPageTracker = _gat._getTracker('UA-8257866-3');
cirerolPageTracker._initData();
cirerolPageTracker._trackPageview();
</script>]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/11/01/state-pattern-enumeration-class-and-fluent-nhibernate-oh-my/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

