생성자 주입 은 종속성을 명시 적으로 만들고 클라이언트가 인스턴스를 제공하도록하는 이점이 있습니다. 또한 클라이언트가 나중에 인스턴스를 변경할 수 없도록 보장 할 수 있습니다. 단점 중 하나는 생성자에 매개 변수를 추가해야한다는 것입니다.
Setter Injection 은 생성자에 매개 변수를 추가 할 필요가 없다는 장점이 있습니다. 또한 클라이언트가 인스턴스를 설정하지 않아도됩니다. 이는 선택적 종속성에 유용합니다. 예를 들어, 기본적으로 실제 데이터 저장소와 같은 클래스를 작성하고 테스트에서 세터를 사용하여 테스트 인스턴스로 대체 할 수있는 경우에도 유용 할 수 있습니다.
내가 알 수있는 한, 인터페이스 주입 은 세터 주입과 크게 다르지 않습니다. 두 경우 모두 나중에 변경 될 수있는 종속성을 선택적으로 설정합니다.
궁극적으로 그것은 선호 와 의존이 필요한지의 문제 입니다. 개인적으로 생성자 주입은 거의 독점적으로 사용합니다. 클라이언트가 생성자에 인스턴스를 제공하도록 강제함으로써 클래스의 종속성을 명시 적으로 만드는 것이 좋습니다. 또한 클라이언트는 사실 후에 인스턴스를 변경할 수 없다는 것을 좋아합니다.
종종 두 가지 별도의 구현을 전달하는 유일한 이유는 테스트 때문입니다. 프로덕션에서는을 전달할 수 DataRepository
있지만 테스트에서는을 전달합니다 FakeDataRepository
. 이 경우 일반적으로 매개 변수가없는 생성자와 a를 허용하는 생성자를 제공합니다 IDataRepository
. 그런 다음 매개 변수가없는 생성자에서 두 번째 생성자에 대한 호출을 연결하고을 전달합니다 new DataRepository()
.
다음은 C #의 예입니다.
public class Foo
{
private readonly IDataRepository dataRepository;
public Foo() : this(new DataRepository())
{
}
public Foo(IDataRespository dataRepository)
{
this.dataRepository = dataRepository;
}
}
이것은 가난한 사람의 의존성 주입으로 알려져 있습니다. 프로덕션 클라이언트 코드에서는 다음과 같은 여러 반복문을 사용하여 반복 할 필요가 없기 때문에 좋아합니다.
var foo = new Foo(new DataRepository());
그러나 테스트를 위해 대체 구현을 계속 전달할 수 있습니다. 나는 가난한 사람의 DI로 의존성을 하드 코딩하고 있다는 것을 알고 있지만 테스트를 위해 주로 DI를 사용하기 때문에 받아 들일 수 있습니다.