Simplistic implementation of a general purpose object serialization API that supports versioning.
Design principles:
- Objects can be stored in different catalogues (think tables in a DB).
- An object is uniquely identified with the tuple catalogue, ID and version.
- The object is serialized into a BLOB field (byte[] array).
- Additionally a Dictionary<string,string> holds freely definable tags
- An example ObjectStore is implemented for ADO.Net databases (SQLite SQL, but overridable)
publicinterfaceIObjectStore{//Access to the serializerIObjectSerializerSerializer{get;}// Gets a single catalogueICatalogueGetCatalogue(stringcode);// Creates a new catalogue (think table in a DB)boolCreateCatalogue(ICataloguecatalogue,booldropifexists=false);// Careful! Deletes entire catalogue! boolDeleteCatalogue(stringcode);// Updates catalogue informationboolUpdateCatalogue(ICataloguecatalogue);//gets all the cataloguesIList<ICatalogue>GetCatalogues();// Deletes all versions of an object! Returns how many records where deleted.intDeleteObject(stringcatalogue,stringID);// Deletes a specific version of an object! Returns how many records where deleted.intDeleteObject(stringcatalogue,stringID,DateTimeversion);//check whether a particular version existsboolExist(stringcatalogue,stringDBID,DateTimeversion);//last version of an IDDateTimeLastVersion(stringcatalogue,stringID);//last version before 'version'DateTimeLastVersion(stringcatalogue,stringID,DateTimeversion);//Create or update a serialized object//tags will be overwritten if updateinfo = trueboolCreateOrUpdate<T>(IObjectInfo<T>info,boolupdateInfo=true);boolCreateOrUpdate(IObjectInfoinfo,boolupdateInfo=true);//get last versionIObjectInfo<T>GetObject<T>(stringcatalogue,stringID);//get last version before 'version'IObjectInfo<T>GetObject<T>(stringcatalogue,stringID,DateTimeversion);//get last versionIObjectInfoGetObjectInfo(stringcatalogue,stringID);//get last version before 'version'IObjectInfoGetObjectInfo(stringcatalogue,stringID,DateTimeversion);//Gets all infos without deserializing the objects of the entire catalogueIList<IObjectInfo>GetAllInfos(stringcatalogue,stringtype="%",boolread_data=false);//Gets all infos without deserializing the objects for an IDIList<IObjectInfo>GetAllInfosForID(stringcatalogue,stringID,boolread_data=false);//Transaction supportIDbTransactionBeginTransaction(IsolationLevelil=IsolationLevel.Unspecified);}The object can be retrieved or stored through the following structure.
publicinterfaceIObjectInfo<T>{stringCatalogue{get;}stringID{get;}DateTimeVersion{get;}stringType{get;}IDictionary<string,string>Tags{get;}TInstance{get;}}But for process interaction it can be beneficial to use the DTO instead.
publicinterfaceIObjectInfo{stringCatalogue{get;}stringID{get;}DateTimeVersion{get;}stringType{get;}IDictionary<string,string>Tags{get;}byte[]Data{get;}intDataSize{get;}}The following interface defines how to serialize the tagging dictionary. Two simplistic serializers (JSON like and .INI like), but these work only for simple key-value pairs.
publicinterfaceITagsSerializer{IDictionary<string,string>Deserialize(stringraw);stringSerialize(IDictionary<string,string>info);}And this is the interface for the object serializer itself.
publicinterfaceIObjectSerializer{TDeserialize<T>(Streamstream);StreamSerialize<T>(Tobj);}Basically any binary serializer would do the trick, but depending on the application one would want to use a legacy serializer or add compression or encryption functionality to the serializer. Using protobuf the serializtion code could be as simple as the following snippet:
usingProtoBuf;namespaceSharpQuant.ObjectStore.Serializers{publicclassProtoObjectSerializer:IObjectSerializer{publicTDeserialize<T>(Streamstream){returnSerializer.Deserialize<T>(stream);}publicStreamSerialize<T>(Tobj){using(varstream=newMemoryStream()){Serializer.Serialize<T>(stream,obj);returnstream;}}}}No object serializers or database frameworks are included in order to not have any external dependancies in the base assembly. However a simple implementation for SQLite could look like the following few lines of code.
namespaceSharpQuant.ObjectStore.SQLite{publicclassSQLiteObjectStore:DbObjectStore{staticFunc<IDbConnection>ConnectionFactory(stringfileName){Func<IDbConnection>Func=()=>{IDbConnectionconn=newSQLiteConnection();conn.ConnectionString="Data Source="+fileName+";";conn.Open();returnconn;};returnFunc;}publicSQLiteObjectStore(stringfileName):base(ConnectionFactory(fileName),newMyObjectSerializer(),newINIInfoSerializer()){}}}