AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Dependency Injection vs Service Locator -- dynamisches Erzeugung von Objekten
Thema durchsuchen
Ansicht
Themen-Optionen

Dependency Injection vs Service Locator -- dynamisches Erzeugung von Objekten

Ein Thema von s.h.a.r.k · begonnen am 1. Aug 2012 · letzter Beitrag vom 5. Aug 2012
Antwort Antwort
Elvis

Registriert seit: 25. Nov 2005
Ort: München
1.909 Beiträge
 
Delphi 2010 Professional
 
#1

AW: Dependency Injection vs Service Locator -- dynamisches Erzeugung von Objekten

  Alt 1. Aug 2012, 16:33
@Elvis:
Bei deiner Lösung habe ich das Problem, dass in jeder Unit, in der ich Objekte erzeuge, der ServiceLocator bekannt sein muss. Ich dachte, dass diese Abhängigkeit eben nicht entstehen sollte. Aber wie schon gesagt, ich bin bisher auf noch keinen grünen Zweig gekommen, der diese Abhängigkeit eleminiert. Ich zweifle auch stark daran, dass ich diese Abhängikeit entfernen kann.

Ich würde je gewünschten Typen eine entsprechende Factory basteln. Den ServiceLocator überall einzubauen wäre eher schlecht für die Lesbarkeit.
Dann packe die IUserFactory als Property in dein UserDings und markiere sie als Dependency.
Wenn du jetzt den TUserFinder durch den DI-Container hochziehst, wird er dort eine passende Instanz von der Factory reinstecken.

Ich selbst habe oft neben den ctor parametern und Properties, die vom DI autom. gefüllt werden, außerdem noch oft den Container in einem Vorfahren deklariert.
Je nach use-case hat man sonst zu viele unnütze Dependencies, die aufgelöst werden müssen, aber in der Lebenszeit des Objektes gar nicht benutzt werden.
Muss man halt abwägen...
Robert Giesecke
I’m a great believer in “Occam’s Razor,” the principle which says:
“If you say something complicated, I’ll slit your throat.”

Geändert von Elvis ( 1. Aug 2012 um 16:35 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#2

AW: Dependency Injection vs Service Locator -- dynamisches Erzeugung von Objekten

  Alt 1. Aug 2012, 16:50
Dann packe die IUserFactory als Property in dein UserDings und markiere sie als Dependency.
Wenn du jetzt den TUserFinder durch den DI-Container hochziehst, wird er dort eine passende Instanz von der Factory reinstecken.
Ich hatte die Hoffnung, dass der DI-Container selbst das erstellen beliebig vieler Objekte automatisch kann und ich gar nicht erst auf einen ServiceLocator zurückgreifen muss.

Ich selbst habe oft neben den ctor parametern und Properties, die vom DI autom. gefüllt werden, außerdem noch oft den Container in einem Vorfahren deklariert.
Je nach use-case hat man sonst zu viele unnütze Dependencies, die aufgelöst werden müssen, aber in der Lebenszeit des Objektes gar nicht benutzt werden.
Muss man halt abwägen...
Jo, das ist mir auch schon durch den Kopf gegangen. AOP ist hier ein Stichwort, zumindest ist mir das hin und wieder im Bezug auf Logging über den Weg gelaufen. Auf der anderen Seite muss ich einfach nur beliebig viele Basis-Objekte definieren, dann kann ich immer vom passenden ableiten
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Elvis

Registriert seit: 25. Nov 2005
Ort: München
1.909 Beiträge
 
Delphi 2010 Professional
 
#3

AW: Dependency Injection vs Service Locator -- dynamisches Erzeugung von Objekten

  Alt 1. Aug 2012, 17:21
Dann packe die IUserFactory als Property in dein UserDings und markiere sie als Dependency.
Wenn du jetzt den TUserFinder durch den DI-Container hochziehst, wird er dort eine passende Instanz von der Factory reinstecken.
Ich hatte die Hoffnung, dass der DI-Container selbst das erstellen beliebig vieler Objekte automatisch kann und ich gar nicht erst auf einen ServiceLocator zurückgreifen muss.
Woher kommt dein TUserFinder?
Hast du ihn direkt aus einem DIC gezogen, oder ist er eine Dependency einer anderen Klasse?
Ist er eine Dependency, dann würde der DIC ja autom. alles machen. Wenn nicht, dann mussu den selbst aus dem Container hochziehen.


Hier mal ein Bleistift, damit wir von der gleichen Sache reden. (Ich nehme einfach an, dass dein DI-Framework [Dependency] als Markierung für Abhängigkeiten verwendet)

Delphi-Quellcode:
type
   TSomeClass = class
   protected
      [Dependency]
      property UserFinder : IUserFinder...;
   public
      function FindUsers(...) : IList<TUser>;
   ...
   TUserFinder = class(IUserFinder)
   protected
      [Dependency]
      property UserFactory : IUserFactory...;
Du hast also irgendeine Klasse, die einen IUserFinder als Property nutzt.
Der wiederum hat eine Property UserFactory.

Würdest du jetzt zum Beispiel das hier machen...
Delphi-Quellcode:
var miep := container.Resolve<TSomeClass>();
miep.FindUsers(...)
...würde der DIC:
  • TSomeClass erzeugen
  • sieht die Dependency-Property
  • packt dir eine IUserFactory rein, die er vllt erst erzeugen muss
  • sieht darin die DependencyProperty
  • packt da die TUserFactory rein
  • sieht deren Dependencies
  • ...

Ich habe da schon ganz schlimme Dinge gesehen, bei denen nicht bedacht wurde was für einen Rattenschwanz das nach sich ziehen kann.
In .Net ist das einfach. Da nimmt man Post# und kann sich (wie du erwähntest) per AOP piepe-einfach die Depencies zu Lazy-Loaded ändern.
In Delphi hassu da keinen, der dir da hilft...

Der Sinn von DI ist ja nicht, dass überall alles von alleine geht (was ja schlecht möglich ist ), man soll die Möglichkeit haben, Implementierungen von außen ändern zu können. (Testbarkeit, Mocks!)
Das geht genauso, wenn man einen Container durchreicht. (Wobei der Container das durchreichen erledigt)
Robert Giesecke
I’m a great believer in “Occam’s Razor,” the principle which says:
“If you say something complicated, I’ll slit your throat.”

Geändert von Elvis ( 2. Aug 2012 um 08:34 Uhr) Grund: Boah, ich glaube ich habe mich in der Disziplin Typos und Edits pro Post ins Olympische Finale editiert...
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#4

AW: Dependency Injection vs Service Locator -- dynamisches Erzeugung von Objekten

  Alt 2. Aug 2012, 08:28
Ich habe mir die Sache nun weiter gründlich durch den Kopf gehen lassen und glaube, dass ich nun mein Problem besser formulieren kann. Dein Beispiel ist gut gewählt und ich würde vorschlagen, dass wir dabei bleiben, wenn wir weiterhin über das Thema diskutieren. Dass die Dependencies entsprechend aufgelöst werden ist ja mein Wunsch, aber scheinbar ist es so, dass nur "1:1-Abhängigkeiten" aufgelöst werden. Es gehen auch 1:N-Beziehungen, aber nur mit einem vorher fest gewählten N -- ich meine damit, dass es fixe N Properties geben muss, die dann entsprechend gefüllt werden. Folgendes klappt scheinbar nicht:
Delphi-Quellcode:
TUserFactory = class
private
  [Dependency(10)]
  FUserList : IList<IUser>;
end;
Ich will mit der 10 andeuten, dass 10 User-Objekte beim Erzeugen des Objekts injiziert werden sollen -- wobei ich doch ganz gerne die Zahl parametrisiert haben wollen würde, sodass ich eigentlich NIE auf den Service Locator zurückgreifen muss. Aber ich wüsste selbst nicht, wie ich diese Problem lösen kann, daher genau dieser Thread hier

Daraus kommt für mich eigentlich nur ein Schluss bei raus: ich *muss* auf den Service Locator immer zugreifen, da ich nur sehr selten eine Anwendung habe, die keine Daten à la User oder Produkte aus einer DB lädt. Nutze ich für die Erstellung einer vorher nicht bekannten, beliebig großen Menge an Objekten (User, Produkte etc.) das Factory-Pattern, so muss jede Factory auf den Service Locator zurückgreifen und ist abhängig davon.

Klar, die Abhängigkeit ist überschaubar und der Gewinn durch den DI-Container, der die Abhängigkeiten der erstellen Objekte entsprechend auflöst, ist echt groß, aber hier könnte man fast noch ein Stückchen mehr nachbessern und den DI-Container optimieren. Aber das ist alles nur Wunschdenken, ohne eine Idee eines eigenen Ansatzes
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  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 14:12 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