L'iniezione sul campo è un po 'troppo "azione spettrale a distanza" per i miei gusti.
Considera l'esempio che hai fornito nel post di Google Gruppi:
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(); }
...
}
Quindi sostanzialmente quello che stai dicendo è che "ho questa classe con stato privato, a cui ho allegato @injectable
annotazioni, il che significa che lo stato può essere automaticamente popolato da qualche agente dall'esterno, anche se il mio stato è stato dichiarato privato "
Capisco le motivazioni per questo. È un tentativo di evitare gran parte della cerimonia che è inerente alla creazione di una classe in modo corretto. Fondamentalmente, quello che si sta dicendo è che "Sono stanco di scrivere tutto questo boilerplate, quindi ho intenzione di annotare tutto il mio stato e lasciare che il contenitore DI si occupi di impostarlo per me."
È un punto di vista perfettamente valido. Ma è anche una soluzione alternativa per le funzionalità linguistiche che probabilmente non dovrebbero essere risolte. Inoltre, perché fermarsi qui? Tradizionalmente, DI si è basato su ogni classe che ha un'interfaccia compagna. Perché non eliminare tutte quelle interfacce con le annotazioni?
Considera l'alternativa (questo sarà C #, perché lo conosco meglio, ma probabilmente c'è un equivalente esatto 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;
}
}
Già conosco alcune cose su questa classe. È una classe immutabile; lo stato può essere impostato solo nel costruttore (riferimenti, in questo caso particolare). E poiché tutto deriva da un'interfaccia, posso sostituire le implementazioni nel costruttore, che è il punto in cui arrivano i tuoi scherzi.
Ora tutto ciò che il mio contenitore DI deve fare è riflettere sul costruttore per determinare quali oggetti ha bisogno di rinnovare. Ma questa riflessione viene fatta su un membro pubblico, in un modo di prima classe; cioè i metadati sono già parte della classe, essendo stati dichiarati nel costruttore, un metodo il cui esplicito scopo è fornire alla classe le dipendenze di cui ha bisogno.
Certo, questo è un gran numero di regole, ma è così che è stato progettato il linguaggio. Le annotazioni sembrano un trucco sporco per qualcosa che avrebbe dovuto essere incorporato nella lingua stessa.