DeHL, Delphi 2010 and Serialization

DeHLA few months have passed and I did not release a new version of DeHL yet. No, it’s not dead. I’ve just been busy with a delicate new feature — Serialization. This post will demonstrate the new capabilities of DeHL it’s advantages and and shortcomings.

But first — since the new releases will focus mostly on serialization and related stuff, I decided to drop Delphi 2009 support. It made no sense to support 2009 for future versions since no essential changes are made to the prior code. You can still use 0.7 release in Delphi 2009.

Back to serialization. The following list describes the changes that went into the new version:

  • In order to support serialization, DeHL’s type system was extended to support Serialize and Deserialize methods. Each type class (that describes a type in Delphi) now knows how to serialize values of the type it manages.
  • A new unit named DeHL.Serialization was added. It contains the base definitions of types used by the type system for serialization.
  • TPointerType, TRecordType<T>, TArrayType<T>, etc. were added for simplified type handling. The old method was a mix-up of Delphi 2009 and Delphi 2010 RTTI specifics (which have some essential differences in my case).
  • All classes can now implement ISerializable interface. The TClassType<T> detects whether this interface is implemented by the object and uses it for serialization (no, reference counting is not touched).
  • DeHL.Serialization.Abstract contains the semi-implementation of a “serializer” and it’s context. It is used by specific serializers.
  • DeHL.Serialization.XML defines the TXMLSerializer<T> which can be used to serialize/deserialize into XML nodes (uses TXMLDocument). Supports it’s own set of attributes (such as XmlRoot, XmlElement, etc.).
  • DeHL.Serialization.Ini defines the TIniSerializer<T> that you can use to serialize/deserialize type into Ini files or registry (through RTL’s TRegIniFile).
  • Most DeHL types (such as Nullable<T>TFixedArray<T>, BigInteger, etc.) provide their own serialization and deserialization methods.
  • All Enex collections (except a few that can’t actually) can be serialized and deserialized. They implement a custom serialization and deserialization technique through ISerializable.

Enough talk, a mandatory example:

  [XmlRoot('Testing', '')]
  TTest = class
    { Pointer to self }
    FSelf: TObject; 
    {A set of format settings }
    FFormatSettings: TFormatSettings;

    { And internal record }
    FInternal: record
      { Force the field to be an attribute of FInternal }
      FOne: Integer;

      { Force this element to have same name but other namespace }
      [XmlElement('Value', '')]
      FTwo: String;

    FListOfDoubles: TList<Double>;
  LDocument: IXMLDocument;
  LXMLSerializer: TXMLSerializer<TTest>;
  LOutInst, LInInst: TTest;
  CoInitializeEx(nil, 0);

  { Initialize the test object }
  LOutInst := TTest.Create;
  LOutInst.FSelf := LOutInst;
  GetLocaleFormatSettings(GetThreadLocale(), LOutInst.FFormatSettings);
  LOutInst.FInternal.FOne := 1;
  LOutInst.FInternal.FTwo := '2 - Two';
  LOutInst.FListOfDoubles := TList<Double>.Create();

  { Create the serializer and an XML document }
  LXMLSerializer := TXMLSerializer<TTest>.Create();
  LDocument := TXMLDocument.Create(nil);

  { Set the options }
  LDocument.Active := true;
  LDocument.Options := LDocument.Options + [doNodeAutoIndent];

  { Force fields to elements by default }
  LXMLSerializer.DefaultFieldsToTags := true;

  { Serialize the structure }
  LXMLSerializer.Serialize(LOutInst, LDocument.Node);

  { Serialize the structure }
  LXMLSerializer.Deserialize(LInInst, LDocument.Node);

  { Cleanup }

The XML file generated by this code looks like this (INI looks uglier):

<Testing xmlns="" xmlns:xsd="" xmlns:xsi="" xmlns:DeHL="" xmlns:NS1="">
  <PointerToSelf DeHL:ref="Testing"/>
    <LongDateFormat>dddd, MMMM dd, yyyy</LongDateFormat>
    <ShortTimeFormat>h:mm AMPM</ShortTimeFormat>
    <LongTimeFormat>h:mm:ss AMPM</LongTimeFormat>
  <FInternal Value="1">
    <NS1:Value>2 - Two</NS1:Value>

On the first serialized/deserialized value, serializers build up a sort of an internal “object graph” and gathers all information about the data being serialized. The next uses of the same serializer instance yield an 10x performance gain since there is no need to rebuild all the information from scratch. I am still working on more optimizations that could give greater speed boost.

P.S. I can’t show the contents of the deserialized object here so you’ll have to take my word for it.

Note. This is just a preview of what is going on in the trunk. No version is released since I have to iron out the last problems and write the missing unit tests.

26 Responses to 'DeHL, Delphi 2010 and Serialization'

  1. Cesar Romero says:

    SVN Update, thank you!

  2. Robert Love says:

    I have been watching your commits, and I like your implementation.
    I have something similar, but really serves to handle things in an identical manner to .NET to the XmlSerializer.

  3. alex says:

    @Robert. Thanks.

    My engine is only for deep serialization. Indeed my XML serialization is not .Net-compatible. But you can use it in a somewhat similar way.

  4. Jon Robertson says:

    We serialize objects to/from DFM quite a bit. We’re able to simply use Delphi’s internal engine, using DefineProperties to provide overrides as necessary. I like the DFM’s format much better than either INI or XML. XML is way too verbose.

    One disadvantage was not being able to treat our serialized object as a data type in SQL Server 2005. But we don’t need this often and wrote a function to extract values from a serialized DFM using string functions.

  5. Bo Sorensen says:

    In the example you are serializing a TList defined as:
    FListOfDoubles: TList;

    Could you outline how to serialize a TList, that contains objects such as this ?
    FMyTList: TList;

    • Maud says:

      Hi Mum,I hae#7&v821n;t read any of Erik’s other posts so I can’t comment on them. I did, however, find the one on nutritionists and dietitians to be accurate and helpful in explaining the distinctions between the professions.

  6. Bo Sorensen says:

    In the above it should read:

    FListOfDoubles: TList(Double)


    FMyTList: TList(TMyObject)

    The commenting system does not like the less- and greater than symbols.

    • Darold says:

      Kewl you suolhd come up with that. Excellent!

    • Caroline says:

      144b5 – 201Thanks so much for giving everyone an exantpioeclly superb possiblity to read articles and blog posts from this web site. It is usually so excellent and also packed with a lot of fun for me and my office colleagues to search your site at the very least 3 times in 7 days to study the fresh tips you have got. And lastly, I’m just at all times fascinated concerning the mind-boggling suggestions served by you. Some 1 points on this page are really the most suitable we have had.c7

    • La mobilité, ok, le licenciement facilité, why not, les contraintes du privés pour le public, pourquoi pas. Mais dans ce cas, que l’on aligne nos salaires sur ceux du privé car si je prends mon cas et celui de ma collègue en face et que je résume : Fonctionnaires, ingénieurs, 10 heures par jour en moyenne (hé oui, il y en a !), et des salaires à 2/3 des salaires moyens du privé sur des postes équivalents (estimation faite d’après un comparatif avec une étude nationale).

  7. Bo Sorensen says:

    It works now after including DeHL.Collections.List instead of including Generics.Collections. The TList definition must be the one from the DeHL framework.

    I really like how easy it is to save a complex object now.

  8. alex says:

    @Bo Sorensen
    Yeah, only DeHL collections are serializable. I was going to add a few modules to be able to seamlessly serialize other RTL-native collections (not TList since it contains opaque pointers).

  9. Hugues VAN LANDEGHEM says:

    I had one problem with deserialisation.

    I had this :
    TPart1 = Class
    field1: string;

    TPart = Class
    part1: TPart1;

    I serialize and deserailize : all work fine.

    But now I want to add TPart2 to TPart like this :

    TPart1 = Class
    field1: string;

    TPart2 = Class
    field2: string;

    TPart = Class
    part1: TPart1;
    part2: TPart2;

    And I’d like to deserialize from TPart XML who was serialized with old TPart (only TPart1) and it fail. Is there a way to make this ?

  10. alex says:

    You should be able to — by annotating the “part2″ field with [XmlNullable]. This will tell the XML serializer to set the “part2″ field to NIL if it does not have an XML node.

    Note that while this is possible it’s not recommended. Deserialized content should be serialized back to the original types otherwise “bad things” may happen.

  11. Lars Fosdal says:

    That XML file has a really bad format. The month and day enumerators assume that the XML is ordered. XML 1.0 is by definition not ordered.

  12. alex says:

    Lars Fosdal :

    That XML file has a really bad format. The month and day enumerators assume that the XML is ordered. XML 1.0 is by definition not ordered.

    A good read about ordering and XML 1.0 can be found here:

    So I would suppose everything is fine.

  13. Hugues VAN LANDEGHEM says:


    and what is the way to add a new field in Part2 like this

    TPart2 = Class
    field2: string;
    newfield2: Boolean;

  14. alex says:

    I don’t understand the question. Email me with the specific problem.


  15. Mathias says:


    I love your library, especially enex and serialization. One thing though: How exactly do I exclude class members from being serialized?

    Thanks for your help, in advance!

  16. alex says:

    put a [NonSerializable] attribute over them.

  17. Tangela says:

    I definitely wanted to type a small comment to be able to thank you for the fantastic techniques you are placing on this website. My codsnierable internet look up has finally been recognized with reasonable strategies to exchange with my pals. I ‘d assert that most of us website visitors are very much endowed to live in a wonderful community with very many special people with very helpful solutions. I feel truly blessed to have seen the website and look forward to tons of more awesome minutes reading here. Thank you once again for all the details.

  18. Oh that looks absolutely STUNNING!! Love it all. I love that you did just the “Merry”. I am big fan of that. (Check out my Christmas banner on my website – hint hint).I love the printed pillow!

  19. Heather – Thank you so much Betsy- you captured the moment beautifully and your words made us shed more tears. We are so proud of our young man and our wonderful daughters.

  20. Super ide!! Så flink mann du har :)Har en mann som bestiller mye fra amazone, så nå tror jeg at jeg skal legge inn et ønske derfra :)Takk for tipset!Klem klem

  1. […] RTTI available in Delphi 2010. A ready-made implementation is available in the DeHL library (here’s a blog post about it) – but I can’t say much about the implementation, I never used […]

Leave a Reply

Your email address will not be published.