2017-04-07 4 views
13

개발중인 응용 프로그램에서 단검 2를 사용하기 시작했는데 단검 2 작동 방식에 대해 몇 가지 질문이 있습니다.단검 2 주입 생성자

@Provides 메소드와 @Inject 주석 뒤에 모든 로직이 있으므로 의존성을 초기화 할 수 있지만 클래스 생성자에 @Inject 주석을 사용하면 버그가 생길 수 있습니다.

이 임은 내 응용 프로그램은, 내가 하나 개의 모듈 내 응용 프로그램의 컨텍스트 검색,의 ContextModule을 정의

을 :

ContextModule.java을

@Module 
public class ContextModule { 

    private final Context context; 

    public ContextModule(Context context) { 
     this.context = context; 
    } 

    @Provides 
    public Context context() { 
     return this.context; 
    } 
} 

이 모듈이 사용되는 예를 들어

내 BaseActivityComponent에 의해 :

BaseActivityComponent.java

@BaseActivityScope 
@Component(modules = ContextModule.class) 
public interface BaseActivityComponent { 
    void injectBaseActivity(BaseActivity baseActivity); 
} 

지금까지 그렇게 좋았습니다. 그런 다음 AuthController 클래스가 있습니다.이 클래스는 컨텍스트에 따라 다르며 BaseActivity에 삽입하려고합니다. 그래서 내 AuthControllers.class에서 내가 좋아하는 뭔가가 있습니다

public class AuthController { 

    private Context context; 

    @Inject 
    public AuthController(Context context) { 
     this.context = context; 
    } 

    public void auth() { 
     // DO STUFF WITH CONTEXT 
    } 
} 

을 그리고 내가 좋아하는 내 BaseActivity에 주입 : 이제

public class BaseActivity extends AppCompatActivity { 

    @Inject 
    AuthController authController; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     BaseActivityComponent component = DaggerBaseActivityComponent.builder() 
      .contextModule(new ContextModule(this)) 
      .build(); 

     component.injectBaseActivity(this); 

     authController.auth(); 

    } 
} 

내 질문은, 어떻게 단검 내 AuthControllers이에 대한 종속성 것을 알고 않습니다 BaseActivity?

@Module(includes = ContextModule.class) 
public class ControllerModule { 

    @Provides 
    AuthController authController(Context context) { 
     return new AuthController(context); 
    } 

} 

그리고 내 BaseActivityComponent에 내가 ControllersModule 내 종속 모듈을 내 AuthController 게터를 추가하고 변경합니다 : : 그냥

@Inject 
AuthController authController; 

내가 같은 ControllerModule을 만든 것처럼이 같은 일처럼 선언하여

내가 injectBaseActivity를 호출 할 때
@BaseActivityScope 
@Component(modules = ControllersModule.class) 
public interface BaseActivityComponent { 

    void injectBaseActivity(BaseActivity baseActivity); 

    AuthController getAuthController(); 
} 

가 (이)는 모든 @Inject 주석 내 클래스의 종속성이있는 단검 한 다음 수색자 내 proje "을 알려줍니다" 해당 유형과 일치하는 주석 처리 된 @ 생성자에 대한 ct?

대거 2에 대한 좋은 점은 모듈 파일이 내 의존성 3의 "문서"로 사용될 수 있다고 생각했습니다. 하지만 컨트롤이있는 모든 생성자에 @Inject를 추가하면 미래에 약간 혼란스럽지 않을 수 있습니다. 실제로 무엇이 무엇에 의존하는지 모르기 때문에? (내 말은, 당신이 무엇에 달려 있는지, 당신은 단지 많은 파일을 찾아서 실제로 찾아야한다는 것을 안다는 뜻이다.)

@Inject 어노테이션을 생성자에서 사용할 때나 @Provides 메소드를 추가 할 때 유용한 모범 사례가 있는가? 모듈 파일에? 생성자에서 @Inject를 사용하면 모듈 파일에서 생성자 정의를 변경할 필요가 없지만 단점이 있습니까?

감사합니다. 내가 injectBaseActivity를 호출 할 때

답변

23

가 (이)는 모든 @Inject 주석 내 클래스의 종속성이있는 단검을, "말한다"다음은 @Inject 그 유형과 일치하는 생성자를 주석에 대한 내 프로젝트를 검색?

정확히. 그러나 injectBaseActivity에 전화 할 때 완료되지는 않지만 컴파일 시간에는 모두 발생합니다. 이것은 주석 처리 (다른 하나는 런타임에 리플렉션을 사용합니다)의 한 방법입니다.

프로젝트를 빌드 할 때 build.gradle 파일에 포함 된 dagger-annotation-processor는 @Inject 주석으로 주석이 달린 모든 필드, 클래스 등의 목록과 함께 호출되고 종속성을 구축합니다 그것으로 그래프. 그런 다음 그래프를 분석하여 그래프의 항목에 대한 모든 종속성을 제공하는 소스 코드를 생성합니다.

injectBaseActivity은 이전에 생성 된 코드를 실행하고 모든 종속성을 객체에 할당합니다. 그것은 당신이 읽고 디버깅 할 수있는 적절한 소스 코드입니다.

컴파일 단계 인 이유 — —을 입력하는 것은 성능 및 유효성 검사입니다.


방법 단검 내 AuthControllers이 BaseActivity에 대한 종속성 것을 알고 않습니다 (일부 종속성 사이클이있는 경우, 예를 들어, 당신은 컴파일 오류가)? 현장 @Inject 단검을 주석으로

@Inject 
AuthController authController; 

은 당신이 AuthController을 원하는 알고있다. 여태까지는 그런대로 잘됐다. 이제 단도는 컨트롤러를 제공하고 구성 요소, 구성 요소 종속성 및 구성 요소 모듈에서 컨트롤러를 찾는 몇 가지 방법을 모색 할 것입니다. 은 해당 생성자에 대해을 알고 있기 때문에 클래스가 자체적으로 제공 될 수 있는지 여부도 알 수 있습니다.

대거는 모듈에 포함시키지 않으면 개체 생성자를 어떻게 알 수 있습니까? 분사와 생성자를 주석으로

@Inject 
public AuthController(Context context) { /**/ } 

당신도 AuthController라는 클래스이고 인스턴스화 할 수 있도록 당신이 문맥을 필요 단검 말했다. 기본적으로 모듈에 추가하는 것과 같습니다.

@Inject 주석을 생성자에 추가하기위한 소스 코드가 없거나 객체를 추가로 초기화해야하는 경우 모듈 @Provides 메서드를 사용해야합니다. 또는 귀하의 경우 ...

[...] 모듈 파일은 내 종속성 트리의 "문서"로 사용될 수 [...] 네, 물론 당신이 할 수

그렇게. 그러나 프로젝트가 커짐에 따라 을 많은 수의 불필요한 코드 인으로 유지해야 할 것입니다. 왜냐하면 생성자의 간단한 주석을 사용하여 동일한 작업을 수행 할 수 있기 때문입니다.

@Inject 주석을 생성자에서 사용하거나 모듈 파일에 @Provides 메서드를 추가 할 때 유용한 모범 사례가 있습니까?

다른 컨텍스트에 다른 버전을 제공하려는 경우 (예 :두 가지 다른 방식으로 인터페이스를 구현) @Binds 주석을 사용하여 단도로 구현 클래스로 제공 할 클래스를 알려줍니다.

나는 가능한 한 항상 생성자 주입을 사용해야한다고 생각합니다. 무언가가 변경되면 코드의 다른 부분을 만질 필요가 없으며 작성하는 코드가 적어 버그를 포함 할 수있는 곳이 적습니다.

또한 단검 수 등을 알아서 많은 최적화 않으며, 불필요한 코드를 구현하는 경우 당신이

결국 물론

을 도입 오버 헤드와 함께 작동하도록해야합니다 그것은 모든를 무엇 당신은 최고라고 생각합니다. 결국 그것은 입니다. 코드와 작동해야하는입니다.

+0

끔찍한 답변입니다. Kotlin 기본 생성자 (클래스 정의로 정의 된 생성자)에 주입 기능을 추가 할 수 있는지 알고 계십니까? –

+1

@saiedVanguard 가능합니다 :'class A @Inject constructor (...)' –