Reputation: 485
I was just wandering if it would be possible to use the Fluent NHibernate to auto map a .Net TcpClient object?
I have a class that has a TcpClient property which I would like to map.
I tried creating a custom class inheriting from TcpClient called tTcpClient and adding an Id Property with a getter/setter; however, it was still looking for the Id field for the base class.
Anyone have any ideas if it is possible, or will I need to create my own xml mapping for the TcpClient?
I was sort of hoping to be able to save the object to easily recreate it on reloading the application and to bind the properties of the TcpClient object to the PropertiesGrid and allowing configuration through that rather easy.
Thanks.
Upvotes: 1
Views: 757
Reputation: 17350
NHibernate does not know how to deal with complex types like TcpClient out of the box. But it lets you provide your own loading and storing code. You can use IUserType:
public class TcpClientMapper : IUserType {
public SqlType[] SqlTypes {
get {
return new[] {
new SqlType(DbType.String),
new SqlType(DbType.Int32)
};
}
}
public Object NullSafeGet(IDataReader rs, String[] names, ...) {
String address = NHibernateUtil.String.NullSafeGet(rs, names[0]);
Int32 port = NHibernateUtil.Int32.NullSafeGet(rs, names[1]);
return new TcpClient(address, port);
}
public void NullSafeSet(IDbCommand cmd, Object value, Int32 index) {
TcpClient tcpClient = value as TcpClient;
if(tcpClient == null) {
NHibernateUtil.String.NullSafeSet(cmd, null, index);
NHibernateUtil.Int32.NullSafeSet(cmd, null, index + 1);
} else {
EndPoint red = tcpClient.Client.RemoteEndPoint;
IPEndPoint endpoint = ((IPEndPoint)red);
NHibernateUtil.String.Set(cmd, endpoint.Address.ToString(), index);
NHibernateUtil.Int32.Set(cmd, endpoint.Port, index + 1);
}
}
public Type ReturnedType {
get { return typeof(TcpClient); }
}
// TODO: implement other methods
}
And map it like this in hbm:
<property name="_tcpClient" type="MyNamespace.TcpClientMapper, MyAssembly">
<column name="Address" /> <!-- NullSafeGet/Set index == 0 -->
<column name="Port" /> <!-- NullSafeGet/Set index == 1 -->
</property>
Or use fluent UserTypeConvention:
public class TcpClientUserTypeConvention : UserTypeConvention<TcpClientMapper> {
}
Upvotes: 2