DeHL project aims to create a useful code library for Delphi 2010+ platform.
The most important features of DeHL for now are:
- A set of generic collections classes (TList, TDictionary, THashSet, TMultiMap, TPriorityQueue and etc).
- Linq-like extensions (called Enex) for collections which allow writing queries on collection classes.
- Date/Time functionality all combined in a few structures (somehow equivalent to .NET’s DateTime structure)
- Type Support concept that defines a set of default “support classes” for each built-in Delphi types (used as defaults in collections). Custom “type support” classes can be registered for your custom data types.
- BigCardinal and BigInteger data types.
- Scoped objects in Delphi.
- Nullable types in Delphi.
- Array extensions and utilities.
- Wide charset implementation.
- Full generic serialization for all included types and collections
- … and more!
All classes and functions have unit tests. We’re trying to maintain a large set of tests to find and fix early all possible bugs. You can find more information about the library here: FeatureList For more information about the design goals see Introduction
All the source code is BSD licensed — you’re free to use it in any commercial application with no restrictions.
I don’t know where to download it?
Here you can find the latest version: http://code.google.com/p/delphilhlplib/downloads/list
Are there code-samples somewhere for DeHL?
Warren
@Warren
Not yet I am afraid. Don’t have enough free time to do them.
Alex, would you mind if some users will try to port your library to the FPC?
It’s BSD-licensed. You can do almost anything to it. But I must warn you – you will most likely fail to port more than a few classes. AFAIK FPC doesn’t support D2010 features (which now stay at the core of the library). Also I don’t know if the generics model is compatible.
Problem 1
————-
Hmmm… Serialization of interfaces isn’t quite working as expected:
IFoo = interface(ISerializable)
end;
TFoo = class(TInterfacedObject, IFoo)
procedure Serialize(const AData: TSerializationData);
procedure Deserialize(const AData: TDeserializationData);
end;
TTest = class
FFoo : IFoo;
public
constructor Create;
end;
{ TFoo }
procedure TFoo.Deserialize(const AData: TDeserializationData);
begin
//
end;
procedure TFoo.Serialize(const AData: TSerializationData);
begin
//
end;
{ TTest }
constructor TTest.Create()
begin
FFoo := TFoo.Create;
end;
Now when I pass a copy of TTest to the serializer (as per your example http://alex.ciobanu.org/?p=285) I get:
“The entity FFoo of type IFoo does not define any serialization/deseriazlion method.”
This seems strange to me as IFoo is inherited from ISerializable.
I prefer using interfaces as fields in my classes as I don’t need to worry about freeing them. This example works fine if I change FFoo : IFoo -> FFoo : TFoo in TTest.
Problem 2
————
By the way I discovered this during investigating another serious problem: I can’t get any of your collection interfaces to serialize naturally (ie. if they are fields in TTest.)
Originally I suspected this was because your base collection interface isn’t derived from ISerializable but having manually changed your code to inherit from ISerializable
Problem 3
————-
Finally… I don’t get something. In your example (http://alex.ciobanu.org/?p=285), TTest is not supporting ISerializable but yet we can serialize it. So why must you insist that member object fields are ISerializable why can’t we just apply the same process to them that is being applied to TTest?!
—-
Thanks for your help in advance. Am I being really stupid?
Regarding problem 3 actually I notice that in fact member fields don’t need to be ISerializable after all…. the other problems still stand though.
@Tim Kelly
Hi Tim., simple answer: interfaces are not serializable. Serialization in my current implementation has to be paired with deserialization. Since an Interface is not bound to any object type, you cannot know the type of the actual object behind it (not without breaking OOP concepts at least) so you cannot deserialize it. What you are seeing is exactly what it says – no serialization method defined for interface types.
As for classes, ISerializable is used to supply you own serialization code if you so choose. The default serialization method (by going recursively) is used on all classes if those do not provide their own ISerializable code.
I am VERY impressed by your library. It should be bundled with Delphi – I can’t imaging coding without it now! One question: I’ve been having a lot of problems with debugging classes nested in generics due to QC bug 84930 (debugger crashes). Given that you have coded a complex library which includes nested generics I was just wondering if a) you have come across this bug and more importantly b) if you have found a work-around / patch for it?
Life without a debugger is not fun!
Thank you!
I employ different techniques when I find these debugging problems, but it mostly works. The newer Delphi versions are pretty stable in this regard.
Alex.
I am trying to make an OwnedObject dictionary (I need a fash object hash). I want the key to be a string and I want the hash to Own the objects. I didn’t seem to get much luck doing a TObjectDictionary as it doesn’t like the key being a string, rather than an object…. please help!
Whoops.. sorry to bother you again… but i’m a bit stuck… I’ve got a list of customobjects and I want to sort them but I don’t quite get how I define the compare algorithm to make one higher in the list over another….
@Tim Kelly
Tim, send me an email at alex [at] ciobanu [dot] org. I’ll try to respond with some explanations or I will update DeHL accordingly.
Alex.
Alex, I have been reading your blog and noticed some mention of documentation you’ve begun. I’d like to see it, though I’m sure you have little time for the writing. Perhaps if it helps me learn the package, I may be able to contribute some writing….
@William Meyer
I will start working on documentation for the 1.0 release. 1.0 will be the stable one in which I am not going to change interfaces. The next release is 0.9 so the documentation is following (0.9 -> 1.0 will be only about docs).
Great stuff! I will watch this one
I love your serialization classes! However, it doesn’t seem as though, when serializing an object based on your TObjectList generic, that it serializes the “OwnsObjects” property. I need it to serialize the property and properly set that value on deserialization.
Is this working as designed? Can you inform me as to how to get the serialization/deserialization of OwnsObjects to work? I’ve tried simple stuff like making it published. I tried to dig into your code, but it went waaaaay to deep for me.
Any help you can give me will be greatly appreciated.
Lee Griffin
@Lee Griffin
Simply put, you should never serialize that value. OwnsObjects is an internal thing and should be controlled by the application and not by the serialized data. But if you really want to:
1. Derive from TObjectList … say TYourList
2. Override StartSerializing and StartDeserializing methods:
procedure StartSerializing(const AData: TSerializationData); override;
procedure StartDeserializing(const AData: TDeserializationData); override;
3. Implement those method as following:.StartDeserializing(const AData: TDeserializationData);
procedure TYourList
var
LOwns: Boolean;
begin
AData.GetValue(‘OwnsItsObjects’, LOwns);
OwnsObjects := LOwns;
inherited;
end;
procedure TYourList.StartSerializing(const AData: TSerializationData);
begin
AData.AddValue(‘OwnsItsObjects’, OwnsObjects);
inherited;
end;
“OwnsItsObjects” is the name given to the serialized property … you can use any other name.
@alex
Thank you! That’s just what I was looking for.
With regards to “never serialize that value”, the way I will be using the lists is that I will have lists of lists of lists (etc.). When I deserialize the lists, the application whould have to traverse the entire heirarchy, setting each list’s “OwnsObjects”. It would be simpler if I could serialize the value–and I can now because of your suggestion.
I’ve been trying to implement a serialization mechanisim for months and never quite got it right. Your routines are just what I have been needing. Thank you so much for them and your help!
Lee
@Lee Griffin
Glad I could help.
Note that external factors can modify the value of that property in the serialized medium and then your app’s behavior is modified.
If you have suggestions, bugs or any other subjects to discuss email me directly. You can find the email in about section (I don’t list it here for spam protection purposes).