Remembering Thoughts
  Twitter GitHub RSS

Custom NHibernate User Type

How to use a custom NHibernate User Type

To store the state of a Risk (ie RiskState) as a value in a column we can use a NHibernate.UserType

The RiskState can be one of the following: (these are all derived from RiskState which implements IRiskState)

Our user type

 public class RiskStateNameUserType: IUserType {
  #region IUserType Members
  public object Assemble(object cached, object owner)  
 {
    return cached;
}
 public object DeepCopy(object value)
{
  return value;
}
public object Disassemble(object value)
{
  return value;
}
  public int GetHashCode(object x)
{
  return x.GetHashCode();
}
public bool IsMutable
{
get {
  return false;
}
  }
  public object NullSafeGet(System.Data.IDataReader dr, string\[\] names, object owner)  
{  
var property0 = NHibernateUtil.String.NullSafeGet(dr, names\[0\]);

if (property0 == null)
{
  return null;
}
IRiskState state;
if (owner is Risk)
{
  state =
    (IRiskState)
  Activator.CreateInstance(Type.GetType(typeof (IRiskState).Namespace + "." + (string) property0),
    owner);
} else
{
  state =
    (IRiskState)
  Activator.CreateInstance(Type.GetType(typeof (IRiskState).Namespace + "." + (string) property0));
}
return state; 
  }   
  public void NullSafeSet(System.Data.IDbCommand cmd, object value, int index)
 {
   if (value == null)
{
    ((IDataParameter) cmd.Parameters\[index\]).Value = DBNull.Value;
   } else
  {
    var state = (IRiskState) value;
  ((IDataParameter) cmd.Parameters\[index\]).Value = state.GetType().Name;
  }
}
  public object Replace(object original,  object target, object owner)
{
    return original;
    }
    public Type ReturnedType
  {
    get {
      return typeof (RiskState);
    }
}
public NHibernate.SqlTypes.SqlType\[\] SqlTypes
{
  get {
    return new\ [\] {
      NHibernateUtil.String.SqlType
    };
    }
  }
  public new bool Equals(object x, object y)
{
  if (x == null && y == null) return true;
  if (x == null || y == null) return false;
  return x.GetType() == y.GetType();
}
#endregion
  }

Using this on a property as follows:

[Property(ColumnType = "Demo.Core.Risks.RiskStateNameUserType, Demo.Core")]
 public IRiskState RequiredState { get; set; }

We can now store types:

image

If importing from a file and we want to parse a string to our user type

    protected T GetCustomType<T>(XElement dsl, string attributeName)
    {
        string attribute = (string)dsl.Attribute(attributeName);
        var customType = (T)Activator.CreateInstance(Type.GetType(typeof(T).Namespace + "." + attribute));
        return customType;
    }

Published:

Share on Twitter