I am trying to serialize custom EntityData class into Eyeshot proprietary file format. There is a great article about this (https://devdept.zendesk.com/hc/en-us/articles/360003318873-Eyeshot-Proprietary-File-Format),
it works fine if I serialize base class, however I can't serialize a class that is derived from my base class. Here is a sample, I tried to keep it as small as possible(please read comments along the way):
public class BaseClass
{
public int Id { get; set; }
public virtual BaseClassSurrogate ConvertToSurrogate() { return new BaseClassSurrogate(this); }
}
public class BaseClassSurrogate : Surrogate<BaseClass>
{
public BaseClassSurrogate(BaseClass myBaseClass) : base(myBaseClass) { }
public int Id { get; set; }
protected override BaseClass ConvertToObject()
{
var baseClass = new BaseClass();
CopyDataToObject(baseClass);
return baseClass;
}
protected override void CopyDataFromObject(BaseClass obj) { Id = obj.Id; }
protected override void CopyDataToObject(BaseClass obj) { obj.Id = this.Id; }
public static implicit operator BaseClass(BaseClassSurrogate surrogate) { return surrogate?.ConvertToObject(); }
public static implicit operator BaseClassSurrogate(BaseClass source) { return source?.ConvertToSurrogate(); }
}
And my derived class with its surrogate implementation:
public class DerivedClass : BaseClass
{
public int Number { get; set; }
public override BaseClassSurrogate ConvertToSurrogate() { return new DerivedClassSurrogate(this); }
}
public class DerivedClassSurrogate : BaseClassSurrogate
{
public DerivedClassSurrogate(DerivedClass baseClass) : base(baseClass) { }
public int Number { get; set; }
protected override BaseClass ConvertToObject()
{
var derivedClass= new DerivedClass();
CopyDataToObject(derivedClass);
return derivedClass;
}
protected override void CopyDataFromObject(BaseClass obj)
{
if (obj is DerivedClass derivedClass)
Number = derivedClass.Number;
base.CopyDataFromObject(obj);
}
protected override void CopyDataToObject(BaseClass obj)
{
if (obj is DerivedClass derivedClass)
derivedClass.Number = Number;
base.CopyDataToObject(obj);
}
//I don't understand do I need to call these in derived class as well?
//public static implicit operator BaseClass(BaseClassSurrogate surrogate) { return surrogate?.ConvertToObject(); }
//public static implicit operator BaseClassSurrogate(BaseClass source) { return source?.ConvertToSurrogate(); }
}
And here is FillModel
method from FileSerializer
class:
protected override void FillModel()
{
base.FillModel();
Model.Add(typeof(BaseClass), false)
.SetSurrogate(typeof(BaseClassSurrogate));
MetaType mt1 = Model[typeof(BaseClassSurrogate)]
.Add(1, "Id");
mt1.SetCallbacks(null, null, "BeforeDeserialize", null);
mt1.UseConstructor = false;
Model.Add(typeof(DerivedClass), false)
.SetSurrogate(typeof(DerivedClassSurrogate));
MetaType mt2 = Model[typeof(DerivedClassSurrogate)]
.Add(1, "Number");
mt2.SetCallbacks(null, null, "BeforeDeserialize", null);
mt2.UseConstructor = false;
}
This code gives me error:"No suitable conversion operator found for surrogate DerivedClass/DerivedClassSurrogate". Any help would be highly appreciated.
In FillModel() method you forgot to specify the hierarchy for your custom classes, try in this way:
protected override void FillModel()
{
base.FillModel();
Model.Add(typeof(BaseClass), false)
.AddSubType(1001, typeof(DerivedClass))
.SetSurrogate(typeof(BaseClassSurrogate));
Model[typeof(BaseClassSurrogate)]
.AddSubType(1001, typeof(DerivedClassSurrogate))
.Add(1, "Id")
.SetCallbacks(null, null, "BeforeDeserialize", null)
.UseConstructor = false;
Model[typeof(DerivedClassSurrogate)]
.Add(1, "Number")
.UseConstructor = false;
}