AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Custom Constructor /DI bei factory-basierter Objekterstellung
Thema durchsuchen
Ansicht
Themen-Optionen

Custom Constructor /DI bei factory-basierter Objekterstellung

Offene Frage von "freimatz"
Ein Thema von Sequitar · begonnen am 27. Jan 2018 · letzter Beitrag vom 26. Mär 2018
Antwort Antwort
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.039 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#1

AW: Custom Constructor /DI bei factory-basierter Objekterstellung

  Alt 7. Feb 2018, 18:18
Du könntest den DI Container von Spring4D einsetzen
Damit kannst du alles injecten, was du willst.

Aber dessen ungeachtet meine Empfehlung: designe den code so, dass du ihn über "pure DI" (sprich, wie würde ich das per hand machen) nutzen kannst - der Einsatz eines wie auch immer gearteten Containers kommt dann bloß oben drauf. Also keine versteckten extra für DI Konstruktoren oder Interfaces.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Sequitar

Registriert seit: 8. Jan 2016
74 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Custom Constructor /DI bei factory-basierter Objekterstellung

  Alt 7. Feb 2018, 22:55
Du könntest den DI Container von Spring4D einsetzen
Damit kannst du alles injecten, was du willst.

Aber dessen ungeachtet meine Empfehlung: designe den code so, dass du ihn über "pure DI" (sprich, wie würde ich das per hand machen) nutzen kannst - der Einsatz eines wie auch immer gearteten Containers kommt dann bloß oben drauf. Also keine versteckten extra für DI Konstruktoren oder Interfaces.
Nachdem was ich hier lese, ist S4D normalerweise perfekt, ich denke nur, dass es den Rahmen sprengt...Zumal man sich da komplett reindenken muss. Bisher hab ich mir halt das meiste selbst angeeignet, oder durch die super betreuung hier im forum^^
Natürlich wird sich sowas bei Großprojekten lohnen, bei mir handelt es sich eher um relativ kleine Anwendungen. However, würde ich auch dort gerne möglichst flexibel bleiben und einen einheitlichen Stil etablieren....

Gut, die Interfaces werd ich wohl nutzen müssen, da ich über dynamisch ladende DLLs arbeite. Daher lass ich mir alle objekte über eine zentrale stelle registieren und kann dann über entsprechende factories, die schnittstellen (intf.) zurückliefern. Das läuft ja alles soweit. Nur verstecken wollte ich eigentlich nichts (ausser wie üblich Encapsulation), mir ist nur noch kein weg eingefallen (normalerweise könnte man das, zb bei statischen packages, mit metaclasses (class of) lösen, aber da ich in den DLLS nicht an die klassen komme, wird das nur bei gemeinsamen vorfahren gehen und lässt sich somit auch relativ schwer verallgemeinern...?

Wie genau ist das mit dem "per Hand machen" (pure DI) gemeint? Ist das nicht sowas wie
Delphi-Quellcode:
Constructor TX.Create(dep:TY;dep2:TZ);
begin
//init with dep,dep2
end;
  Mit Zitat antworten Zitat
freimatz

Registriert seit: 20. Mai 2010
1.490 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Custom Constructor /DI bei factory-basierter Objekterstellung

  Alt 8. Feb 2018, 10:25
Nachdem was ich hier lese, ist S4D normalerweise perfekt, ich denke nur, dass es den Rahmen sprengt...Zumal man sich da komplett reindenken muss. Bisher hab ich mir halt das meiste selbst angeeignet, oder durch die super betreuung hier im forum^^
Natürlich wird sich sowas bei Großprojekten lohnen, bei mir handelt es sich eher um relativ kleine Anwendungen. However, würde ich auch dort gerne möglichst flexibel bleiben und einen einheitlichen Stil etablieren....
1. Also wenn du dich schon mit "Custom Constructor /DI bei factory-basierter Objekterstellung" beschäftigst, dann lohnt sich das Reindenken auf jeden Fall. Oder umgekehrt kannst auch gleich das Thema lassen.
2. Der Unterschied ist nicht zwischen groß und klein, sondern eher Hobby oder beruflich. Wenn Du professionell Softwareentwickler bist, dann musst du m.E. dich eh in das Thema reindenken.

Geändert von freimatz ( 8. Feb 2018 um 10:27 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.039 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#4

AW: Custom Constructor /DI bei factory-basierter Objekterstellung

  Alt 8. Feb 2018, 10:35
Wie genau ist das mit dem "per Hand machen" (pure DI) gemeint? Ist das nicht sowas wie
Delphi-Quellcode:
Constructor TX.Create(dep:TY;dep2:TZ);
begin
//init with dep,dep2
end;
Ja, mit dem kleinen unterschied, dass der Konstruktor am besten auch interfaces injected bekommt und nicht Objekte.

Pure DI ist dann das hier:

Delphi-Quellcode:
var
  x: IX;
  y: IY;
  z: IZ;
begin
  y := TY.Create(...);
  z := TZ.Create(...);
  x := TX.Create(y, z);
Und genau das macht ein DI Container auch. Wenn du ein IX haben willst, weiß er, dass er erst ein IY und IZ braucht (also TY und TZ bauen muss, evtl mit deren Abhängigkeiten) und gibt die dann beim Konstruktoraufruf mit.

Ich hab vor einiger Zeit mal nen Mini DI Container gebaut, der das schon kann - ohne das ganze fancy Extra Zeugs, was der Spring Container kann.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Sequitar

Registriert seit: 8. Jan 2016
74 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Custom Constructor /DI bei factory-basierter Objekterstellung

  Alt 12. Feb 2018, 16:32
Wie genau ist das mit dem "per Hand machen" (pure DI) gemeint? Ist das nicht sowas wie
Delphi-Quellcode:
Constructor TX.Create(dep:TY;dep2:TZ);
begin
//init with dep,dep2
end;
Ja, mit dem kleinen unterschied, dass der Konstruktor am besten auch interfaces injected bekommt und nicht Objekte.

Pure DI ist dann das hier:

Delphi-Quellcode:
var
  x: IX;
  y: IY;
  z: IZ;
begin
  y := TY.Create(...);
  z := TZ.Create(...);
  x := TX.Create(y, z);
Und genau das macht ein DI Container auch. Wenn du ein IX haben willst, weiß er, dass er erst ein IY und IZ braucht (also TY und TZ bauen muss, evtl mit deren Abhängigkeiten) und gibt die dann beim Konstruktoraufruf mit.

Ich hab vor einiger Zeit mal nen Mini DI Container gebaut, der das schon kann - ohne das ganze fancy Extra Zeugs, was der Spring Container kann.
Danke für die Infos,
So hab ich mir das auch vorgestellt.(IY;IZ zu nutzen ist naturlich sehr sinnvoll). Das problem bei dieser Lösung ist nur dass ich bis auf ausnahmen der in einem gemeinsamen package declarierten Typen nicht so einfach anwenden kann. (Also entweder müsste ich auf statische packages zurück, alle Klassen irgendwo gemeinsame Vorfahren mit Constructor TBase.Create(a,b,c:iirgendwas);virtual; haben lassen oder es gibts noch einen anderen weg,über DLL's  X:=Tx.create(y:ianinterface,z:ianotherinterface) zu finden und mit Params Y und Z aufzurufen (evtl RTTI, so wie im o.g beispielsimple DI container)?
Und genau DAS ist zzt mein problem...ohne parameter ist ja einfach>>Tclass

Geändert von Sequitar (12. Feb 2018 um 16:39 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.039 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#6

AW: Custom Constructor /DI bei factory-basierter Objekterstellung

  Alt 12. Feb 2018, 17:24
Die Interfaces sollten in einem Package sein (allein aus dem Grund, damit alle beteiligten Module, dieselbe Typeinfo nutzen, sonst funktioniert das mit dem Container per RTTI nicht).

Und Parameter finden musst du selber dann gar nicht. Du sagst dem Container, es gibt X, Y und Z und dann weiß er, was er zusammen tackern muss, wenn du ein IX brauchst (nämlich nen IY und IZ, die er auch allein baut).
Für weitere Informationen einfach mal Dependency Injection in Delphi lesen
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Sequitar

Registriert seit: 8. Jan 2016
74 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: Custom Constructor /DI bei factory-basierter Objekterstellung

  Alt 12. Feb 2018, 23:13
Die Interfaces sollten in einem Package sein (allein aus dem Grund, damit alle beteiligten Module, dieselbe Typeinfo nutzen, sonst funktioniert das mit dem Container per RTTI nicht).

Und Parameter finden musst du selber dann gar nicht. Du sagst dem Container, es gibt X, Y und Z und dann weiß er, was er zusammen tackern muss, wenn du ein IX brauchst (nämlich nen IY und IZ, die er auch allein baut).
Für weitere Informationen einfach mal Dependency Injection in Delphi lesen
OK so hab ichs bisher gemacht, Registrierung und interfaces in ein gemeinsames package.

Nachfrage:Ich hab nur noch nicht ganz verstanden, wie ich denn den container mit iy,iz füttere (das meinte ich mit parametern) damit er n ix ausgibt.(ausser er würde den spezifischen konstruktor für die implementierende klasse kennen,was sich bei einigen wohl machen liesse,bei denen ich genau weiss ich kann ein class of ....einsetzen, weil die basisklasse schon mit im ReGpackage steckt aber nicht als OSFA). ich mein wahrscheinlich wärs am einfachsten mit setter injection nur wärs mir am liebsten ich wüsste direkt dass ich alles komplett hab wenn das objekt erstellt wird.
ich guck mir mmal das buch an, vlt find ich da ja was passendes....merci
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.039 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#8

AW: Custom Constructor /DI bei factory-basierter Objekterstellung

  Alt 13. Feb 2018, 08:48
Hier mal ein kleines Beispiel:

Delphi-Quellcode:
program Simple_DI;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  SimpleContainer in 'SimpleContainer.pas';

type
  IX = interface
    ['{E2D88E1C-AE7D-491A-B456-84B134749890}']
  end;

  IY = interface
    ['{3D1256AB-CDDE-49B2-94CF-E9FA82314206}']
  end;

  IZ = interface
    ['{4F51DE5D-B65B-4776-B25B-5B2868DC34AC}']
  end;

  TX = class(TInterfacedObject, IX)
  private
    fy: IY;
    fz: IZ;
  public
    constructor Create(const y: IY; const z: IZ);
  end;

  TY = class(TInterfacedObject, IY)
    constructor Create;
  end;

  TZ = class(TInterfacedObject, IZ)
    constructor Create;
  end;

{ TX }

constructor TX.Create(const y: IY; const z: IZ);
begin
  Writeln('creating ', ClassName);
  Writeln('injected ', (y as TObject).ClassName, ' for y');
  Writeln('injected ', (z as TObject).ClassName, ' for z');

  fy := y;
  fz := z;
end;

{ TY }

constructor TY.Create;
begin
  Writeln('creating ', ClassName);
end;

{ TZ }

constructor TZ.Create;
begin
  Writeln('creating ', ClassName);
end;

var
  container: TSimpleContainer;
  x: IX;
begin
  // showing the so called register, resole, release (RRR) pattern
  // see http://blog.ploeh.dk/2010/09/29/TheRegisterResolveReleasepattern/

  container := TSimpleContainer.Create;
  try
    // register
    container.Add<IX, TX>;
    container.Add<IY, TY>;
    container.Add<IZ, TZ>;

    // resolve
    x := container.Get<IX>;
  finally
    // release
    x := nil;
    container.Free;
  end;
end.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight

Geändert von Stevie (13. Feb 2018 um 08:50 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:31 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz