현장 주입은 내 취향 에 따라 너무 "먼 거리에서 바보 같은 행동" 입니다.
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;
}
}
이미이 수업에 대해 알고 있습니다. 불변의 클래스입니다. 상태는 생성자 (이 경우 참조)에서만 설정할 수 있습니다. 그리고 모든 것이 인터페이스에서 파생되므로 생성자에서 구현을 바꿀 수 있습니다. 여기서 모의가 나오는 곳입니다.
이제 DI 컨테이너는 생성자를 통해 반영하여 새로운 객체가 필요한 객체를 결정합니다. 그러나 그 반성은 일류 방식으로 공개 회원 에게 이루어지고 있습니다 . 즉, 메타 데이터는 이미 클래스의 일부이며 생성자에서 선언되었으며 클래스의 목적은 클래스에 필요한 종속성을 제공하는 것입니다.
이것은 많은 상용구이지만, 언어가 설계된 방식입니다. 주석은 언어 자체에 내장되어 있어야 할 내용에 대한 더러운 해킹처럼 보입니다.