In den meisten Beispielen für die Abhängigkeitsinjektion werden einfache Objekte angezeigt, wie im folgenden Beispiel SecurityManager in MainApplication eingefügt wird.
Es wäre jedoch natürlich, auch Delegierte zu verwenden, da im Beispiel LogHandler in MainApplication eingefügt wird.
>Werden Delegierte in der Regel nicht für die Abhängigkeitsinjektion verwendet? Was wären Gründe für und gegen ihre Verwendung?
%Vor%Ich benutze gelegentlich Delegierte als Anonymous Interfaces - auch für DI.
Ein Problem bei diesem Ansatz besteht jedoch darin, dass es schwieriger wird, Unit-Tests durchzuführen, wenn die korrekte Abhängigkeit in eine Klasse injiziert und verwendet wurde, da eine Delegate-Instanz kein Typ ist und manchmal auch Ich möchte einfach nur überprüfen, dass eine Klasse den richtigen Typ von Strategie / Abhängigkeit verwendet.
Ich weiß, dass MEF zum Beispiel erlaubt, Delegierte zu injizieren. Sie können jedoch auch eine ILog-Schnittstelle erstellen, die über eine Log-Methode mit der gleichen Signatur verfügt wie Ihr Stellvertreter. Ich denke, es wird viel klarer zu verstehen sein, dass die Absicht darin bestand, eine Implementierung eines Objekts, das protokollieren kann, anstelle einer einzelnen Protokollfunktion einzufügen.
Wenn wir zurück zu objektorientierten Prinzipien gehen, ist eines der Hauptmerkmale eines Objekts, dass es Verhalten und state hat. Ich könnte mir ein Szenario vorstellen, in dem ein Log-Handler eine Art Status (Logfilename, Db-Verbindung usw.) verwalten muss, aber es kann auch ein Argument geben, dass sich ein Log-Handler nicht mit dem Status beschäftigen muss.
Wenn Ihre Abhängigkeit ihren eigenen Status verwalten muss, verwenden Sie ein geeignetes Objekt (eher eine Schnittstelle).
Wenn Ihre Abhängigkeit nur Verhalten und nicht Status hat, dann könnte ein Delegat geeignet sein, obwohl einige Leute es trotzdem einfacher finden, ein richtiges Objekt (Schnittstelle) zu verwenden, da es später einfacher sein kann, die Zustandsverwaltung hinzuzufügen benötigt.
Ein Vorteil von Delegierten besteht darin, dass sie VERRÜCKT sind, einfach mit Lambda-Ausdrücken zu verhätscheln :) (obwohl Schnittstellen auch leicht zu verspotten sind)
Nun kann natürlich jeder Delegat immer noch irgendeine normale Methode für ein normales Objekt sein, und diese Methode kann völlig Verhalten haben, das den Zustand des Objekts beeinflusst, und es gibt sicherlich gültige Gründe, das zu tun, aber Sie nähern sich der Punkt, an dem es sinnvoller ist, nur eine Abhängigkeit vom gesamten Objekt zu nehmen, anstatt nur eine seiner Methoden.
Weiter unten auf diesem Pfad können Sie durch das Einfügen von Delegierten auch das Interface-Trennungsprinzip anwenden, damit Sie sichergehen können Ihr System ist nicht von Dingen abhängig, die es nicht verwendet.
Es gibt fast nie einen guten Grund, einen eigenen Delegattyp zu definieren. Die meisten Anwendungsfälle passen in die Typen Func<>
und Action<>
C # (und Ereignisse, aber das ist ein anderes Problem).
In Ihrem Fall sollte Ihr MainApplication
-Konstruktor kein Window1.LogHandler
als Parameter, sondern nur ein Action<string>
verwenden. Dann würdest du es einfach anrufen mit:
oder ähnlich, da die ConsoleLogHandler
-Methode bereits die Action<string>
-Signatur enthält.
Und in Ihrem Test würden Sie es einfach installieren mit:
%Vor%oder noch besser:
%Vor%Dann können Sie überprüfen, ob MainApplication die Methode genau so oft aufgerufen hat, wie Sie es beabsichtigt haben.
Tags und Links c# dependency-injection delegates