You know... it was already solved, but some internal change made this not working anymore.
The thing is this:
The method OnDeserialized is implemented, it's protected virtual and overridable for you, precisely for the purpose you want. Though, it's now never called. The reason is that it was called from FixupDeserialization, however that routine was later on cleared up as it was no longer needed. This effectively orphaned OnDeserialized. This thus wasn't noticed. It wasn't called from the template, which was a mistake.
The thing can be 'solved' in two ways: (not really solved, see below).
- by calling OnDeserialized from the template
or
- by calling OnDeserialized from the FixupDeserialization() routine.
I think it's 'best 'to do the first, as the latter is called in every deserialization constructor. (the Fixup routine is now empty btw).
The problem though is that this routine is a little problematic: the routine should only be called once, and worse: from the leaf of the hierarchy. Though in every class there's a deserialization constructor to deserialize the parts of that class.
This means that if the OnDeserialized routine is called from the deserialization constructor, it will deserialize potentially the members of a class which deserialization constructor hasn't run yet which could lead to problems as data which is assumed to be there isn't there yet.
In theory this could be done in code generation, testing to see if a type is a subtype and a leaf and if so, emit the call. The problem is that if an inheritance hierarchy changes (subtype gets a subtype), the code of the developer could lead to hard-to-trackdown issues at runtime, if the override of OnDeserialized of the subtype is now again overriden for the new subclass.
Say you have Employee <- Manager <- Boardmember.
The deserialization constructor of Boardmember first calls the deserialization constructor of MAnager which calls first the deserialization constructor of Employee. If in the deserialization constructor of Employee a call to OnDeserialized is done, and it's overriden in Boardmember, the method cant assume the deserialization constructor of boardmember has ran as it hasn't. So the best way is to have private methods called at the end of each deserialization constructor routine. However that's only possible if the call is added to a region instead of a protected method which is called always and which is overriden if required.
If I add a region to the derived entity class, it would be best. Then, you're free to either call OnDeserialized() or call your private routine.
(edit) the regions are added, so in the next build these regions are present in the generated code: derived entity, 2-class scenario selfservicing, deserialization constructor.