Schränkt das DI-Muster die Erstellung teurer Objekte in Verbindung mit einer seltenen Abhängigkeitsabhängigkeit ein?

8

Es fällt mir schwer, mich mit einem Problem zu beschäftigen, das offensichtlich ist, wenn es um die typische Abhängigkeitsinjektion von Konstruktoren geht. Zum Beispiel, sagen wir, ich habe einen ASP.NET MVC3-Controller, der wie folgt aussieht:

%Vor%

Die Sache, die mir schwer fällt, ist die Tatsache, dass der DI-Container aufgefordert wurde, alle drei Abhängigkeiten zu instanziieren, wenn zu einem bestimmten Zeitpunkt nur eine Teilmenge der Abhängigkeiten benötigt wird die Aktionsmethoden auf diesem Controller.

Es wird angenommen, dass die Konstruktion von Objekten unbemerkt ist und es keine Nebeneffekte bei der Objekterstellung gibt ODER alle Abhängigkeiten konsistent verwendet werden . Was, wenn die Objektkonstruktion nicht billig war oder Nebenwirkungen auftraten? Wenn zum Beispiel das Erstellen von IServiceA das Öffnen einer Verbindung oder das Zuordnen anderer signifikanter Ressourcen zum Inhalt hat, dann wäre dies eine völlig verschwendete Zeit / Ressourcen, wenn ActionB aufgerufen wird.

Wenn diese Aktionsmethoden ein Servicelokationsmuster (oder ein anderes ähnliches Muster) verwenden würden, gäbe es niemals die Möglichkeit, unnötig unnötige Objektinstanzen zu konstruieren. Natürlich sind bei Verwendung dieses Schemas andere Probleme unattraktiv.

Sperrt die Verwendung des kanonischen Konstruktorinjektion + Interfaces -Musters von DI den Entwickler grundsätzlich in eine "Beschränkung" von Arten, dass Implementierungen der Abhängigkeit cheep sein müssen, um instanziieren oder die Instanz signifikant genutzt werden muss? Ich weiß, dass alle Muster ihre Vor- und Nachteile haben, ist das nur einer der Nachteile von DI? Ich habe es nie zuvor erwähnt, was ich seltsam finde.

    
ckittel 05.08.2011, 18:05
quelle

4 Antworten

6

Wenn Sie viele Felder haben, die nicht von jedem Mitglied verwendet werden, bedeutet dies, dass die Kohäsion der Klasse niedrig ist. Dies ist ein allgemeines Programmierkonzept - Constructor Injection macht es nur besser sichtbar . Es ist normalerweise ein ziemlich guter Indikator dafür, dass das Prinzip der einheitlichen Verantwortung verletzt wird.

Wenn dies der Fall ist, dann refactor (z. B. Fassadendienste ).

Sie müssen sich beim Erstellen von Objektdiagrammen nicht um die Leistung sorgen .

>

Wenn es um Nebenwirkungen geht, sollten ( Konstruktoren einfach sein und keine Nebenwirkungen haben ) a>.

    
Mark Seemann 08.08.2011, 05:30
quelle
5

Generell sollte es keine größeren Kosten oder Nebenwirkungen der Objektkonstruktion geben. Dies ist eine allgemeine Aussage, von der ich glaube, dass sie auf die meisten (nicht alle) Objekte zutrifft, aber sie gilt insbesondere für Dienste, die Sie über DI einspeisen würden. Mit anderen Worten, das Erstellen einer Serviceklasse führt automatisch einen Datenbank- / Service-Aufruf durch oder ändert den Zustand Ihres Systems auf eine Weise, die (zumindest) einen Code-Geruch nach sich ziehen würde.

In Bezug auf Instanzen, die nicht verwendet werden: Es ist schwierig, ein System zu erstellen, das Instanzen in abhängigen Klassen perfekt nutzt, unabhängig davon, ob Sie DI verwenden oder nicht. Ich bin mir nicht sicher, ob dies erreicht werden kann, solange Sie sich an das Prinzip der einheitlichen Verantwortung halten. Wenn Sie feststellen, dass in Ihrer Klasse zu viele Services injiziert wurden oder die Auslastung wirklich ungleichmäßig ist, könnte dies ein Zeichen dafür sein, dass Ihre Klasse zu viel tut und in zwei oder mehr kleinere Klassen aufgeteilt werden muss gezieltere Verantwortlichkeiten.

    
Phil Sandler 05.08.2011 19:45
quelle
2

Nein, Sie sind nicht an die Beschränkungen gebunden, die Sie aufgelistet haben. Ab .net 4 haben Sie Lazy (Of T) zu Ihrer Verfügung, die es erlauben wird Sie können die Instanziierung Ihrer Abhängigkeiten aufschieben, bis sie benötigt werden.

Es wird nicht angenommen, dass die Objektkonstruktion spottbillig ist und folglich einige DI-Container% co_de unterstützen % out of the box. Während Unity 2.0 die faule Initiali- sierung durch automatische Fabriken Es gibt einen guten Artikel hier zu einer Erweiterung, die unterstützt Lazy(Of T) hat der Autor auf MSDN .

    
Pero P. 05.08.2011 18:46
quelle
0

Ist Ihr Controller kein Singleton? Das ist der normale Weg, dies in Java zu tun. Es wurde nur eine Instanz erstellt. Sie können den Controller auch in mehrere Controller aufteilen, wenn die Rollen der Aktionen so eindeutig sind.

    
david 05.08.2011 18:47
quelle