I'm writing an Ocean plugin for Petrel and need to persist some custom domain objects, and everything seems to point to using a structured archive data source. I've created a common class to hold a lot of the standard domain object stuff (droid, name, color, image, comments, history, etc), to avoid rewriting it for every domain object I create. The Ocean development guide only has simple examples of classes with no inheritance, but given that everything has a version number, I foresee a potential problem when the base class version is different than the version of inherited-class-1 which is different than inherited-class-2, and then I update something in the base class.
Is it possible to use a structured archive with the common base class? Are there any special considerations for versioning, or anything else I need to be aware of?
ETA: A simple class diagram showing the relationships and some stuff I've tried
public abstract class ClassA
|
-----------------------------------
| |
public class ClassB : ClassA public classC : ClassA
public class ClassD
{
private List<ClassA> _myClassAObjects;
}
All classes are marked Archivable
, and in ClassD
, _myClassAObjects
is marked Archived
. Everything saves OK, but when I load, I get an InvalidCastException
, as it tries to cast the List<ClassB>
to a List<ClassA>
. The casting should work, since ClassB
inherits from ClassA
, should it not?
Got an answer from Schlumberger. It is possible, by doing something like this:
[Archivable]
public abstract class Abstract CDO
{
[ArchivableContextInject]
protected StructuredArchiveDataSource DataSourceCore;
[Archived(Name = "Name")]
private string _name;
private AbstractCDO _parent;
[Archived(Name="ParentDroid")]
private Droid _parentDroid;
[Archived(Name = "Droid")]
protected Droid DroidCore
{
get { return _droid; }
set
{
if (_droid != value)
{
DataSourceCore.IsDirty = true;
_droid = value;
}
}
}
public Droid ParentDroid
{
get { return _parentDroid; }
set
{
if (_parentDroid != value)
{
DataSourceCore.IsDirty = true;
_parentDroid = value;
}
}
}
public AbstractCDO Parent
{
get { return _parent; }
set
{
if (_parent != value)
{
DataSourceCore.IsDirty = true;
_parent = value;
_parentDroid = _parent.Droid;
}
}
}
protected AbstractCDO(string name)
{
_name = name;
DataSourceCore = Factory.Get();
_droid = DataSourceCore.GenerateDroid();
DataSourceCore.AddItem(_droid, this);
}
}
[Archivable]
public abstract class AbstractCDOCollection : AbstractCDO, IObservableElementList
{
[Archived]
private List<AbstractCDO> _children;
protected AbstractCDO(string name) : base(name) { }
public List<AbstractCDO> Children
{
get { return _children; }
}
}
[Archivable]
public class ConcreteObject : AbstractCDO
{
public ConcreteObject(string name) : base(name)
{
// other stuff
}
}
The DataSource property needs to be protected since the injection had a bug which was fixed in Petrel 2013.3 / 2014.1.