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

Custom Constructor /DI bei factory-basierter Objekterstellung

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

Registriert seit: 20. Mai 2010
1.513 Beiträge
 
Delphi 11 Alexandria
 
#1

AW: Custom Constructor /DI bei factory-basierter Objekterstellung

  Alt 29. Jan 2018, 07:44
Leider kann ich dir nicht direkt weiterhelfen. Was ich sagen kann ist, dass es geht auf die Parameter der Konstruktoren einer Klasse zuzugreifen. Unser selbstgeschriebener Dependecy-Container kann das zumindest. Der Code der den Contrainer verwendet benutzt jedoch nie den Konstruktor für andere Parameter. Der Konstruktor wird nur verwendet um Abhängigkeiten zu injizieren. Weitere Werte kommen dann auch per Methoden oder Eigenschaften rein.
(Es gab hier mal eine Diskussion den Dependecy-Container zu erweitern, so dass man auch die berüchtigen "AOwner" Parameter übergeben kann. Ich gehe aber davon aus, dass der Dependecy-Container dann eine weitere Methode bekommen hätte.)
  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 29. Jan 2018, 09:58
Leider kann ich dir nicht direkt weiterhelfen. Was ich sagen kann ist, dass es geht auf die Parameter der Konstruktoren einer Klasse zuzugreifen. Unser selbstgeschriebener Dependecy-Container kann das zumindest. Der Code der den Contrainer verwendet benutzt jedoch nie den Konstruktor für andere Parameter. Der Konstruktor wird nur verwendet um Abhängigkeiten zu injizieren. Weitere Werte kommen dann auch per Methoden oder Eigenschaften rein.
(Es gab hier mal eine Diskussion den Dependecy-Container zu erweitern, so dass man auch die berüchtigen "AOwner" Parameter übergeben kann. Ich gehe aber davon aus, dass der Dependecy-Container dann eine weitere Methode bekommen hätte.)

Okay danke für die Antwort schonmal. es ging mir ja auch hauptsächlich um die von dir genannten abhängingkeiten
Wie habt ihr denn diese Konstruktoren aufgerufen (gemeinsame baseclass?), in welcher form waren die angängigkeiten? ich natürlich kann ich werte per eigenschaften über diverse interfaces setzen , aber das Problem (bei euch gings ja irgendwie) was ich hab, ist dass ich durch die factory ja nicht Tx.Create(Anint: Integer) aufrufen kann, ausser wenn ich ne basisklasse bereits kenne die den konstruktor zumindest abstrakt kennt.

Das mit den interfaces ist ein eigentlich praktikabler ansatz, den ich auch bisher verfolge, nur kann ich bei Objekterstellung halt den nutzer nicht ZWINGEN, möglicherweise notwendige initiale abhängigkeiten zu übergeben, bevor ers vlt vergisst als property zuzuweisen..., ausserdem bräuchte ich dann bei jedem "receiver" einer injektion dann sowas wie "Finjectable.init", also müsste ich dann ein extra interface erstellen, das von allen möglichen dependencies zu implementieren wäre...geht zwar, find ich aber irgenwie unpraktisch und unschön dazu.


Zitat:
Was ich sagen kann ist, dass es geht auf die Parameter der Konstruktoren einer Klasse zuzugreifen
...Ist das nicht das, was ich gerade denke nich zu können?^^
Wie ist das gemeint? b) wie wäre das denn möglich? Via RTTI, vielleicht, damit hab ich bisher noch fast gar keuine Erfahrung.Merci

Geändert von Sequitar (29. Jan 2018 um 10:02 Uhr)
  Mit Zitat antworten Zitat
freimatz

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

AW: Custom Constructor /DI bei factory-basierter Objekterstellung

  Alt 29. Jan 2018, 15:06
Ja RTTI - und auch ich habe da fast keine Erfahrung damit.
  Mit Zitat antworten Zitat
Sequitar

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

AW: Custom Constructor /DI bei factory-basierter Objekterstellung

  Alt 7. Feb 2018, 10:34
Hab das jetzt so zu lösen versucht. Nicht elegant und definitiv ausbaufähig(je nachdem wo man als nächstes gegen eine wand läuft) //bisher fiel mir keine bessere Lösung ein für das problem, als ein neues interface einzuführen auf das bei erstellung geprüft wird und bei erfolg die enstprechenden abhängigkeiten mitgegeben werden. Man KÖNNTE das dann wohl auch über delegates den einzelen objekten mitgeben, damit die nicht so "hässlich" werden. Die frage bleibt ob das nicht auch einfacher / eleganter geht??
Delphi-Quellcode:
Type
//Nachteil? IInjectable müsste dann von jedem "abhängigen" object implementiert werden (zb auch über delegates)

  Iinjectable = Interface
    ['{ECC8E26C-7D14-43FD-9247-066435DAEDA4}']
    Procedure Inject(Dependencies: Array Of Iinterface);
    // Function DependsOn(Dependency: Tobject): Boolean;
  End;

  Tinjectfactory = Class(Tifactory) Class
  Function New(Classname: String; Dependencies: Array Of IInterface)
    : Iinterface;overload; Static;
  End;
//[...]
Class Function Tinjectfactory.New(Classname: String;
  Dependencies: Array Of IInterface): Iinterface;
Var
  Temp: Iinjectable;
Begin
  Result := {inherited} New(Classname);//new(param:string)inherited from parent class
  Try
    If Supports(Result, Iinjectable, Temp)
    Then
      Temp.Inject(Dependencies);
  Except
    Raise
  End;
End;

//Nutzungsbeispiel

Procedure Tinjecttest.Test_factoryinject;
Var
  Parent: Iinterface;
  Bla: Ibla;
Begin
  Try
    Tinjectfactory.Register([Tinjectabletestobject, Tbla, Tblub]);
    Parent := Tinjectfactory.New('Tinjecttest.Tinjectabletestobject',
      [Tbla.Create, Tblub.Create]); //statt direkterstellung auch zb verschachtelung mehrerer "abhängiger" factoryaufrufe
    // assert(iinjectable(parent).dependson())
    (Parent As Ibla).Bla;
    (Parent As Iblub).Blub;
    Bla := Parent As Ibla;
    Bla.Bla;
    Tinjectfactory.UnRegister([Tinjectabletestobject, Tbla, Tblub]);
  Except
    On E: Exception Do
      Raise E
  End;
End;

Geändert von Sequitar ( 7. Feb 2018 um 12:50 Uhr) Grund: Beispiel eingefügt; Formatierung
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

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

AW: Custom Constructor /DI bei factory-basierter Objekterstellung

  Alt 7. Feb 2018, 17: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
 
#6

AW: Custom Constructor /DI bei factory-basierter Objekterstellung

  Alt 7. Feb 2018, 21: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.513 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Custom Constructor /DI bei factory-basierter Objekterstellung

  Alt 8. Feb 2018, 09: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 09:27 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

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

AW: Custom Constructor /DI bei factory-basierter Objekterstellung

  Alt 8. Feb 2018, 09: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
Antwort Antwort

 
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 21:58 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-2025 by Thomas Breitkreuz