Using Spring4D with TAurelius

I want to use TAurelius with Spring4D for its ease of use of ILIST<T>

I've written an Unit (see below) and wished to have the point of view Wagner if he's got enought time for it...

--Sorry for the post if you consider it too long--

(* Code sample using the unit below*
uses
Aurelius.ObjectManager,uAureliusSpringManager;
...
Procedure Test;
var
Manager:TObjectManger;
begin
...
// initialize Manager and load from DB
.....
Manager.FindPerson.ForEach(procedure (const P:TPerson)
begin
// do whatever with current P
...
end);
...
// releas Manager
end;

(*Unit *)

unit uUtilAureliusObjectManager;

interface

uses
  Aurelius.Engine.ObjectManager, Aurelius.Criteria.Base, Spring.Collections,
  uDataObjects, Aurelius.Bind.Dataset, System.Generics.Collections;

type
  (* *************** *)
  (* TPerson *)
  (* Class sample *)
  (* *************** *)
  TPerson = class
  private
    FId: Integer;
    FName: String;
  public
    property Id: Integer read FId write FId;
    property Name: String read FName write FName;
  end;

  (* *************** *)
  (* TIListObject *)
  (* Class Conversion TListObject<T> toward ILIST<T>)
    (**************** *)

TIListObject < T: class >= class(TObjectList<T>)
function ILIST: ILIST<T>;
function Enumeration: IEnumerable<T>;
class function ObjectListToIList(aListe: TObjectList<T>): ILIST<T>;
end;

(* *************** *)
(* TAureliusDatasetEx *)
(* Class Helper to use ILIST with TAureliusDataset *)
(* *************** *)

TAureliusDatasetEx = class helper
for TAureliusDataset
  procedure Ilist2ObjectList<E: class>(SourceList: ILIST<E>;
  var aListe: TObject);
end;

(* *************** *)
(* TCriteriaEx *)
(* Customizing TCriteria *)
(* *************** *)

TCriteriaEx = class helper
for TCriteria private
  function GetIList<E: class>: ILIST<E>;
  public
    function ListePersons: ILIST<TPerson>;
end;

(* *************** *)
(* TCriteriaPerson *)
(* TCriteria upon TPerson class *)
(* *************** *)
TCriterePerson = TCriteria<TPerson>;

(* *************** *)
(* TObjectManagerEx *)
(* Class Helper to directly use customised TCriteria *)
(* *************** *)
TObjectManagerEx = class helper
for TObjectManager
  function FindPerson: TCriterePerson;
end;

implementation

(* *************** *)
(* TObjectManagerEx *)
(* Class Helper to directly use customised TCriteria *)
(* *************** *)

function TObjectManagerEx.FindPerson: TCriterePerson;
begin
  result := TCriterePerson(Self.CreateCriteria<TPerson>);
end;

{ TCriterePerson }

function TObjectManagerEx.FindPerson: TCriterePerson;
begin
  result := Self.CreateCriteria<TPerson> as TCriterePerson;
end;

{ TCriteriaEx }

function TCriteriaEx.GetIList<E>: ILIST<E>;
begin
  result := uUtileSpring.TIListObject<E>.ObjectListToIList(Self.List<E>);
end;

function TCriteriaEx.ListePersons: ILIST<TPerson>;
begin
  result := GetIList<TPerson>;
end;

{ TAureliusDatasetEx }

procedure TAureliusDatasetEx.Ilist2ObjectList<E>(SourceList: ILIST<E>;
  var aListe: TObject);
var
  A: TArray<E>;
  LO: TObjectList<E>;
begin
  if Assigned(aListe) then
    aListe.DisposeOf;
  SetLength(A, SourceList.Count);
  A := SourceList.ToArray;
  LO := TObjectList<E>.Create(FALSE);
  LO.AddRange(A);
  Self.SetSourceList(LO);
  aListe := LO;
end;

{ TIListObject<T> }

function TIListObject<T>.Enumeration: IEnumerable<T>;
begin
  result := Self.ILIST;
end;

function TIListObject<T>.ILIST: ILIST<T>;
var
  Item: T;
  E: IEnumerable<T>;
  A: TArray<T>;
begin
  SetLength(A, Self.Count);
  A := Self.ToArray;
  result := TCollections.CreateObjectList<T>(A, FALSE);
end;

class function TIListObject<T>.ObjectListToIList(aListe: TObjectList<T>)
  : ILIST<T>;
var
  A: TArray<T>;
begin
  SetLength(A, aListe.Count);
  A := aListe.ToArray;
  result := TCollections.CreateObjectList<T>(A, aListe.OwnsObjects);
  if not aListe.OwnsObjects then
    aListe.Free;
end;

end.
Sorry, there are some errors in my code (simplifying brings errors....)

Procedure Test;
var
Manager:TObjectManger;
begin
...
// initialize Manager and load from DB
.....
Manager.FindPerson.ListPerson.ForEach(procedure (const P:TPerson)
begin
// do whatever with current P
...
end);
...
// release Manager
end;

Hi Thomas,


Thanks, it could a be a good start for users trying to use Spring4D.
I don't know much about such framework, doesn't it have simply a wrapper for TList<T> that would easily create an IList<T> from a Delphi TList<T>?
This way all of that could be simplified, as you could just use something like


SpringList := ToIList<TPerson>(Manager.Find<TPerson>.List);


I think that would be the easiest and more generic approach?

Helas! I've no read any such wrapper but i may be getting blind: https://spring4d.4delphi.com/docs/master/Html/index.htm?Spring.Collections.IList(T).IndexOf(T).htm

Writing in the generic way ( aSprinList:= ToList<T>(Manager.Find<T>.List) is getting more and more annoying to type while the code gets bigger and bigger... besides reading is somewhat esoteric.

So i prefer my way... Using my librairy i can write :

1) Entities.pas
..
Type
[Entity]
 
[Automapping]
TPerson = class
private
  FId: integer;
  FLastName: string;
  FFirstName: string;
  FEmail: string;
public
  property Id: integer read FId;
  property LastName: string read FLastName write FLastName;
  property FirstName: string read FFirstName write FFirstName;
  property Email: string read FEmail write FEmail;
end;Implementation
...
end;

2)  EntitiesHelper.pas;
..
uses
Entities...
Type
Tperson_Ex=class helper for TPerson
(* mimics TStoreProcedure : usefull in some DB like SQlite ..*)
function HasMeetingWith(aPerson,aDate:TDateTime):Boolean;
end;

implementation
...
3)
Uase
uses
Entities,EntitiesHelper,...

Me:=Tperson.create;

NextVisitor:= MyObjectManager.FindPerson.ListPerson.First(Function (Const aPerson:Tperson):Boolean begin
Result:=Me.HasMeeting(aPerson,Now);
end);

Thomas,


I use both Spring and Aurelius and considered the same question before. Then, I realised that I did not really need to use IList instead of TList as generated by Aurelius.

There are some methods attached to IList which can be very useful but in fact you can get everything by adjusting the projections and the queries in the Aurelius statements.