Tuesday, December 19, 2006

Generic NHibernate Enum String Mapping

Today one of my coworkers mentioned all the little NHibernate enum mapping turd classes that were accumulating in our data access layer.  See this post for more details on how it works and why you would want to do this.  I wondered aloud if generics could be used to eliminate this waste of disk space.  A few minutes later, this is what we came up with.

public class GenericEnumMapper<TEnum> : EnumStringType
{
public GenericEnumMapper() : base(typeof(TEnum))
{
}
}

To use this class in your NHibernate mapping file, just use the following lovely .NET 2.0 generics syntax in your "type" attribute:

MyNamespaceB.GenericEnumMapper`1[[MyNamespaceA.MyEnum,
MyAssemblyA]], MyAssemblyB

No, that ` is not an apostrophe, it's a backtick.  It lives on the same key as ~ on my keyboard.


Here it is in a sample hbm.xml mapping file:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="MyNamespaceA.UserCredential, MyAssemblyA"
table="UserCredential" lazy="false">
<id name="Id" column="ID" type="Guid">
<generator class="guid.comb" />
</id>
<property name="UserId" />
<property name="CredentialType" column="CredentialTypeID"
type="MyNamespaceB.GenericEnumMapper`1[[MyNamespaceA.CredentialType,
MyAssemblyA]], MyAssemblyB"
/>
...
</class>
</hibernate-mapping>

Copy, paste, and replace CredentialType with your own enum type, and you're good to go!