Польова ін'єкція - це занадто "моторошна дія на відстані" на мій смак.
Розглянемо приклад, який ви вказали у своїй публікації в групах Google:
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(); }
...
}
Отже, в основному, ви говорите, що "я маю цей клас із приватною державою, до якої я додав @injectable
анотації, це означає, що держава може бути автоматично заселена якось агентом ззовні, навіть якщо мій штат був оголошений приватним. "
Я розумію мотивацію до цього. Це спроба уникнути значної частини церемонії, властивої правильному встановленню класу. По суті, те, що можна сказати, - це, що я втомився писати всю цю табличку, тому я просто збираюся пояснити весь свій стан, і дозвольте контейнеру DI подбати про його встановлення ".
Це абсолютно правильна точка зору. Але це також вирішення мовних особливостей, над якими, напевно, не слід працювати. Крім того, навіщо зупинятися на цьому? Традиційно, DI покладався на кожен клас, що має супутній інтерфейс. Чому б також не усунути всі ці інтерфейси з анотаціями?
Розглянемо альтернативу (це буде C #, тому що я знаю це краще, але, можливо, є точний еквівалент у 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;
}
}
Я вже знаю деякі речі про цей клас. Це непорушний клас; стан може бути встановлений лише в конструкторі (посилання в цьому конкретному випадку). А оскільки все походить від інтерфейсу, я можу поміняти місцями реалізації в конструкторі, саме там надходять ваші макети.
Тепер все, що я повинен зробити, це - це відображення над конструктором, щоб визначити, які об'єкти потрібно створити. Але ця рефлексія робиться на публічному члені першокласно; тобто метадані вже є частиною класу, оголошеними в конструкторі, методом, чіткою метою якого є надання класу залежностей, які йому потрібні.
Зрозуміло, що це багато котельних плит, але саме так було розроблено мову. Анотації здаються брудним злом для чогось, що повинно було бути вбудовано в саму мову.