For those who may be interested in the wrapper pattern I am currently using to implement custom serialization with OrmLite (works with other ORMs too), here is a simple working example with NodaTime
types that are otherwise not serialized properly:
public class BusinessObject {
public class Poco {
public readonly BusinessObject BusinessObject;
public Poco(BusinessObject businessObject) {
this.BusinessObject = businessObject;
}
public Poco() {
this.BusinessObject = new BusinessObject();
}
public string Id {
get { return this.BusinessObject.Id; }
set { this.BusinessObject.Id = value; }
}
public decimal Amount {
get { return this.BusinessObject.Amount; }
set { this.BusinessObject.Amount = value; }
}
public DateTime Dt {
get { return this.BusinessObject.Dt.ToDateTime(); }
set { this.BusinessObject.Dt = LocalDateTime.FromDateTime(value).Date; }
}
public string TimeZone {
get { return this.BusinessObject.TimeZone.Id; }
set { this.BusinessObject.TimeZone = DateTimeZoneProviders.Tzdb.GetZoneOrNull(value); }
}
public string Description {
get { return this.BusinessObject.Description; }
set { this.BusinessObject.Description = value; }
}
}
public string Id { get; private set; }
public decimal Amount { get; private set; }
public LocalDate Dt { get; private set; }
public DateTimeZone TimeZone { get; private set; }
public string Description { get; private set; }
public BusinessObject() { }
public BusinessObject(string id, decimal amount, LocalDate dt, DateTimeZone timeZone, string description) {
this.Id = id;
this.Amount = amount;
this.Dt = dt;
this.TimeZone = timeZone;
this.Description = description;
}
}
I hope it will soon be possible to define hooks/callbacks for specific types that should be handled with custom code, and also that OrmLite will allow properties with private setters to be reloaded from persistence (currently it will only work in one direction).
Update (2014/03/08): As a temporary workaround, it is possible to have OrmLite use custom serialization/deserialization by calling first:
JsConfig<BusinessObject>.TreatValueAsRefType = true;
Even if BusinessObject
is a reference type. Then, you can enjoy the beauty/simplicity/ubiquity of:
JsConfig<BusinessObject>.RawSerializeFn = bo => bo.Serialize();
JsConfig<BusinessObject>.RawDeserializeFn = str => BusinessObject.Deserialize(str);
Hopefully support for custom mapping will be added soon (so that for example a NodaTime.LocalDate can be mapped to a DateTime instead of a string).