Die Feldinjektion ist für meinen Geschmack ein bisschen zu "gruselig in der Ferne" .
Betrachten Sie das Beispiel, das Sie in Ihrem Google Groups-Beitrag angegeben haben:
public class VeracodeServiceImplTest {
@Tested(fullyInitialized=true)
VeracodeServiceImpl veracodeService;
@Tested(fullyInitialized=true, availableDuringSetup=true)
VeracodeRepositoryImpl veracodeRepository;
@Injectable private ResultsAPIWrapper resultsApiWrapper;
@Injectable private AdminAPIWrapper adminApiWrapper;
@Injectable private UploadAPIWrapper uploadApiWrapper;
@Injectable private MitigationAPIWrapper mitigationApiWrapper;
static { VeracodeRepositoryImpl.class.getName(); }
...
}
Sie sagen also im Grunde: "Ich habe diese Klasse mit privatem Status, an die ich @injectable
Anmerkungen angehängt habe , was bedeutet, dass der Status automatisch von einem Agenten von außen ausgefüllt werden kann, obwohl mein Status als privat deklariert wurde . "
Ich verstehe die Gründe dafür. Es ist ein Versuch, einen Großteil der Zeremonie zu vermeiden, die der ordnungsgemäßen Einrichtung einer Klasse innewohnt. Grundsätzlich heißt es: "Ich bin es leid, all dieses Boilerplate zu schreiben, also werde ich einfach meinen gesamten Zustand mit Anmerkungen versehen und den DI-Container sich darum kümmern lassen, es für mich einzustellen."
Es ist eine vollkommen gültige Sichtweise. Es ist jedoch auch eine Problemumgehung für Sprachfunktionen, die möglicherweise nicht umgangen werden sollten. Auch warum dort aufhören? Traditionell hat sich DI darauf verlassen, dass jede Klasse eine Companion-Schnittstelle hat. Warum nicht auch alle diese Schnittstellen mit Anmerkungen entfernen?
Überlegen Sie sich die Alternative (dies wird C # sein, weil ich es besser kenne, aber es gibt wahrscheinlich ein genaues Äquivalent in Java):
public class VeracodeService
{
private readonly IResultsAPIWrapper _resultsApiWrapper;
private readonly IAdminAPIWrapper _adminApiWrapper;
private readonly IUploadAPIWrapper _uploadApiWrapper;
private readonly IMitigationAPIWrapper _mitigationApiWrapper;
// Constructor
public VeracodeService(IResultsAPIWrapper resultsApiWrapper, IAdminAPIWrapper adminApiWrapper, IUploadAPIWrapper uploadApiWrapper, IMitigationAPIWrapper mitigationApiWrapper)
{
_resultsAPIWrapper = resultsAPIWrapper;
_adminAPIWrapper = adminAPIWrapper;
_uploadAPIWrapper = uploadAPIWrapper;
_mitigationAPIWrapper = mitigationAPIWrapper;
}
}
Ich weiß schon einiges über diese Klasse. Es ist eine unveränderliche Klasse; state kann nur im Konstruktor gesetzt werden (Referenzen in diesem speziellen Fall). Und weil alles von einer Schnittstelle herrührt, kann ich Implementierungen im Konstruktor austauschen.
Jetzt muss mein DI-Container nur noch über den Konstruktor nachdenken, um zu bestimmen, welche Objekte neu erstellt werden müssen. Aber diese Reflexion wird auf erstklassige Weise über ein öffentliches Mitglied gemacht ; Das heißt, die Metadaten sind bereits Teil der Klasse und wurden im Konstruktor deklariert. Diese Methode hat den ausdrücklichen Zweck, der Klasse die Abhängigkeiten zur Verfügung zu stellen, die sie benötigt.
Zugegeben, das ist eine Menge Boilerplate, aber so wurde die Sprache entworfen. Anmerkungen scheinen ein schmutziger Hack für etwas zu sein, das in die Sprache selbst eingebaut werden sollte.