How to handle circular reference unit with Aureliu

I know how to do that with regular classes, but since Aurelius does RTTI stuff I dont know what to do...


the problem is this:

UnitA

uses UnitB;

type
    tclassA =
        FClassB:
TClassB;
    end;

----------------------------
UnitB

uses
UnitC;

type
    tclassB =
        FClassC: TClassC;
   
end;

----------------------------
UnitC

uses UnitA;  
<------------- back to beginning

type
    tclassC =
       
FClassA: TClassA;
    end;

It is circular because it comes back on the 3rd unit.

The problem came up on my TEntityItem that has a List of TEntityComposicao that has a List of TEntityComposicaoItems and that has a List of TEntityItem;

I thought the compiler would handle that since it was not a deadlock with 2 units, that it could resolve with 3.

What is the solution based on Aurelius for that? Did you have any case like that?

thanks !

It's a Delphi issue, not Aurelius. You have to put all classes in same unit.

I know it is Delphi issue... but since Aurelius READ RTTI I dont know what is acceptable for Aurelius in a case like that,


this is the bottom line of my question...

but i will go for all together in the same unit... my deadline is too close now.... thanks you helped me

Why it's different because Aurelius uses RTTI? The classes should compile anyway to have RTTI info.

A way to solve circular references is to go for a base class.


instead TList<TEntityItem>   i could use TList<TObject>  

and in the IMPLEMENTATION I reference the use of my unit with TEntityItem and in the code use typecast.

That works for the circular reference. WHAT I DONT KNOW and it is real reason of my questions, is what it will looks like for Aurelius since it uses RTTI to read the class definition...

am I thinking wrong?

That will not work with Aurelius since it relies on compile-time information about types. Even for Delphi usage, that's a kludge. A best approach would be having a TBaseEntityItem declared in a separate unit and then having TEntityItem inherit from it, and declaring the list as TBaseEntityItem.

but does TBaseEntityItem needs to have the [Entity] tag?


I can use that idea, however I dont want to be joinedtables, since I have already 3 levels of joinedtables with EntityItem. 

I understand that I needed to:

change TEntityItem to TBaseEntityItem  (like when we create delphi components, everything is the TBase....)

create a new TEntityItem that only inherits from TBaseEntityItem.

The base class will have tags for the fields

but only the TEntityItem will have the [Entity] tag:

<snip>

  [Id('ID', TIdGenerator.Guid)]
TBaseEntityItem = class
    FId: TGuid;
end;

  [Entity]
  [Table('ITEM')]
  [Inheritance(TInheritanceStrategy.JoinedTables)]    <- this for the subclasses from this level and down
TEntityItem = class(TBaseEntityItem)
<<fields where defined in the base class>>
end;


Does it work for Aurelius?

You have to put all attributes in the class that is going to be mapped (the actual Aurelius entity). So, you should:

1. Declare your TBaseEntityItem
2. Add the common properties to TBaseEntityItem that you are going to use in your Delphi code only. (I mean, for your code to work fine, the properties that make sense to put in TBaseEntityItem
3. Create TEntityItem inheriting from TBaseEntityItem, and put ALL mapping attributes in it. This way the classes will behave as a hierarchy in Delphi code, but for Aurelius, only TEntityItem exists and will be persisted.