Im vergangenen Jahr habe ich ein neues System mit Dependency Injection und einem IOC-Container erstellt. Das hat mir viel über DI beigebracht!
Ich halte es jedoch auch nach dem Erlernen der Konzepte und Muster für eine Herausforderung, Code zu entkoppeln und einen IOC-Container in eine Legacy-Anwendung einzuführen. Die Anwendung ist so groß, dass eine echte Implementierung überwältigend wäre. Auch wenn der Wert verstanden und die Zeit gewährt wurde. Wer hat Zeit für so etwas?
Ziel ist es natürlich, Unit-Tests in die Geschäftslogik einzubinden!
Geschäftslogik, die mit testverhindernden Datenbankaufrufen verknüpft ist.
Ich habe die Artikel gelesen und verstehe die Gefahren von Poor Man's Dependency Injection, wie in diesem Artikel von Los Techies beschrieben . Ich verstehe, dass es nichts wirklich entkoppelt.
Ich verstehe, dass es viel systemweites Refactoring beinhalten kann, da Implementierungen neue Abhängigkeiten erfordern. Ich würde nicht in Betracht ziehen, es für ein neues Projekt mit beliebiger Größe zu verwenden.
Frage: Ist es in Ordnung, Poor Man's DI zu verwenden, um Testbarkeit in eine Legacy-Anwendung einzuführen und den Ball ins Rollen zu bringen?
Ist die Verwendung von Poor Man's DI als Basisansatz für echte Abhängigkeitsinjektion eine wertvolle Methode, um über die Notwendigkeit und den Nutzen des Prinzips zu informieren?
Können Sie eine Methode umgestalten, die eine Datenbankaufrufabhängigkeit und eine Zusammenfassung aufweist, die hinter einer Schnittstelle aufgerufen wird? Allein diese Abstraktion würde diese Methode testbar machen, da eine Scheinimplementierung über eine Konstruktorüberladung übergeben werden könnte.
Sobald die Bemühungen Befürworter gewinnen, könnte das Projekt aktualisiert werden, um einen IOC-Container zu implementieren, und die Konstrukteure, die die Abstraktionen aufnehmen, wären da draußen.
I consider it a challenge to decouple code and introduce an IOC container into a legacy application
natürlich ist es. Es heißt technische Schulden. Aus diesem Grund sind kleine und fortlaufende Refaktoren vor allen größeren Umbauten vorzuziehen. Die größten Konstruktionsfehler zu reduzieren und auf IoC umzusteigen, wäre weniger schwierig.Antworten:
Die Kritik an Poor Man's Injection in NerdDinner hat weniger damit zu tun, ob Sie einen DI-Container verwenden oder nicht, als dass Sie Ihre Klassen korrekt einrichten .
In dem Artikel heißt es, dass
ist falsch, da der erste Konstruktor zwar einen praktischen Fallback-Mechanismus zum Erstellen der Klasse bereitstellt, aber auch eine enge Abhängigkeit zu erstellt
DinnerRepository
.Das richtige Mittel ist natürlich nicht, wie Los Techies vorschlägt, einen DI-Container hinzuzufügen, sondern den fehlerhaften Konstruktor zu entfernen.
Die Abhängigkeiten der verbleibenden Klasse werden nun ordnungsgemäß invertiert. Sie können diese Abhängigkeiten nun beliebig einfügen.
quelle
XService
Parameter an einen übergebenXRepository
und das zurückgegeben wird, was er zurückgibt, ist für niemanden übermäßig nützlich und bietet auch in Bezug auf die Erweiterbarkeit nicht viel. Schreiben Sie Ihre Komponententests, um ein aussagekräftiges Verhalten zu testen, und stellen Sie sicher, dass Ihre Komponenten nicht so eng sind, dass Sie Ihre gesamte Logik auf Ihre Kompositionswurzel verlagern.Sie machen hier eine falsche Annahme darüber, was "der DI des armen Mannes" ist.
Das Erstellen einer Klasse mit einem "Shortcut" -Konstruktor, der immer noch eine Kopplung erzeugt, ist keine DI für den armen Mann.
Das Fehlen eines Behälters und das manuelle Erstellen aller Injektionen und Zuordnungen ist die DI des armen Mannes.
Der Begriff "DI des armen Mannes" klingt nach einer schlechten Sache. Aus diesem Grund wird der Begriff "reines DI" heutzutage empfohlen, da er positiver klingt und den Prozess genauer beschreibt.
Es ist nicht nur absolut in Ordnung, DIs / pure DIs von Armen zu verwenden, um DIs in eine vorhandene App einzuführen, sondern auch eine gültige Methode, DIs für viele neue Anwendungen zu verwenden. Und wie Sie sagen, sollte jeder an mindestens einem Projekt pure DI verwenden, um wirklich zu verstehen, wie DI funktioniert, bevor er die Verantwortung auf die "Magie" eines IoC-Containers überträgt.
quelle
Paragidm-Verschiebungen in Legacy-Teams / Codebasen sind äußerst riskant:
Wenn Sie ein DI-Framework als Hammer verwenden, um alle Nägel zu zertrümmern, wird Legacy-Code in allen Fällen eher schlechter als besser. Es ist auch persönlich äußerst riskant.
Selbst in den seltensten Fällen, wie zum Beispiel wenn es in Testfällen verwendet werden soll, werden die Testfälle zu "nicht-standardmäßigen" und "fremden" Codes, die bestenfalls markiert werden,
@Ignore
wenn sie beschädigt werden oder sich ständig über sie beschweren Legacy-Programmierer mit der größten Schlagkraft im Management und mit all dieser "verschwendeten Zeit für Komponententests", die nur Ihnen angelastet wird, werden "richtig" umgeschrieben.Abhängigkeitsinjektion ist eine Lösung, die nach einem Problem sucht.
Die Abhängigkeitsinjektion ist nur in kleinen Dosen für einen sehr engen Bereich von Dingen nützlich:
Dinge, die sich stark ändern oder viele alternative Implementierungen haben, die statisch gebunden sind.
Pluginsysteme mit konfigurierbaren Plugins, die in Ihrem Framework im Konfigurationscode definiert und beim Start automatisch erkannt und während der Ausführung des Programms dynamisch geladen / neu geladen werden können.
quelle