2017-02-24 6 views
0

내 응용 프로그램에서 dagger2 종속성을 이해했으며 많은 예제를 통해이를 설정했습니다. 내가 찾지 못한 것은 일단 그들이 주입되면 모든 의존성을 사용하는 적절한 방법이다.Dagger2 전체 의존성 그래프 사용

모듈의 각 싱글 톤은 앞에 싱글 톤의 출력에 따라 다릅니다. 필요한 모든 입력을 얻기 위해 각 싱글 톤을 차례로 호출하지 않고 전체 종속성 그래프를 어떻게 사용합니까?

다음 감안할 때 :

AppComponent

@Singleton 
@Component(modules = { 
     DownloaderModule.class 
}) 
public interface AppComponent { 
    void inject(MyGameActivity activity); 
} 

DownloaderModule

@Module 
public class DownloaderModule { 

    public static final String NETWORK_CACHE = "game_cache"; 

    private static final int GLOBAL_TIMEOUT = 30; // seconds 

    public DownloaderModule(@NonNull String endpoint) { 
     this(HttpUrl.parse(endpoint)); 
    } 

    @Provides @NonNull @Singleton 
    public HttpUrl getEndpoint() { 
     return this.endpoint; 
    } 

    @Provides @NonNull @Singleton @Named(NETWORK_CACHE) 
    public File getCacheDirectory(@NonNull Context context) { 
     return context.getDir(NETWORK_CACHE, Context.MODE_PRIVATE); 
    } 

    @Provides @NonNull @Singleton 
    public Cache getNetworkCache(@NonNull @Named(NETWORK_CACHE) File cacheDir) { 
     int cacheSize = 20 * 1024 * 1024; // 20 MiB 
     return new Cache(cacheDir, cacheSize); 
    } 

    @Provides @NonNull @Singleton 
    public OkHttpClient getHttpClient(@NonNull Cache cache) { 
     return new OkHttpClient.Builder() 
       .cache(cache) 
       .connectTimeout(GLOBAL_TIMEOUT, TimeUnit.SECONDS) 
       .readTimeout(GLOBAL_TIMEOUT, TimeUnit.SECONDS) 
       .writeTimeout(GLOBAL_TIMEOUT, TimeUnit.SECONDS) 
       .build(); 
    } 

MyGameApp

public class MyGameApp extends Application { 

    private AppComponent component; 

    private static Context context; 

    public static MyGameApp get(@NonNull Context context) { 
     return (MyGameApp) context.getApplicationContext(); 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     component = buildComponent(); 
     MyGameApp.context = getApplicationContext(); 

     } 

    public AppComponent component() { 
     return component; 
    } 

    protected AppComponent buildComponent() { 
     return DaggerAppComponent.builder() 
       .downloaderModule(new DownloaderModule("https://bogus.com/")) 
       .build(); 
    } 

} 
+1

"이전에 싱글 톤의 출력에 달려 있습니까?" 모듈은 각 조각을 해당'@ Provides' 메서드의 입력 매개 변수로 가져 와서 필요한 각 요소를 주입 할 수 있도록 잘 구조화 된 것 같습니다. MyGameActivity 내에서 생성 한'OkHttpClient' 나 다른 의존성을 삽입 할 수 있어야합니다. –

+0

나는 머리에 곧바로 직면하는 데 어려움을 겪고있다. 좀 더 읽고 개념이 침몰하고 있습니다. 실망한 것은 설정하는 방법을 보여주는 수많은 기사가 있지만 실제 사용 예제를 찾기가 어렵습니다. 나는 괜찮은 모범을 보이고있다. 감사. –

답변

1

나는이에 도움이 되거하려고 노력하지만, 거기에 있습니다을당신이 이것을 읽을 수있는 몇 가지 방법. 나는 밑바닥 접근법을 선호한다 - 기본적으로 당신의 물건이 필요로하는 것을 시작하고 내 방식대로 작업한다. 이 경우에는 MyGameActivity에서 시작합니다. 불행히도 코드를 붙여 넣지 않았기 때문에 조금 창의적이어야하지만 운동 목적으로는 괜찮습니다.

따라서 앱에서는 AppComponent이 표시되고 MyGameActivityinject입니다. 그래서 저는이 활동에 주사 가능한 분야가 있다고 생각합니다. 내가 직접 거기에 OkHttpClient을 사용하고 있는지 잘 모르겠지만 말하려합니다. 예 :

public class MyGameActivity extends SomeActivity { 
    @Inject 
    OkHttpClient okHttpClient; 
    // ... 
} 

내가 생각하는 방식은 다음과 같습니다. Dagger는 AppComponent에 의해 주어진 OkHttpClient이 필요하다는 것을 알고 있습니다. 그래서 이것을 제공 할 수있는 방법을 살펴 보겠습니다. 생성자에 @Inject으로 주석을 추가했기 때문에 객체 자체를 빌드 할 수 있습니까? 더 많은 의존성이 필요합니까?

이 경우이 클라이언트가 제공되는 구성 요소의 모듈을 조사합니다. getHttpClient에 도달하면 Cache 개체가 필요하다는 것을 알게됩니다. 이 객체가 제공 될 수있는 방법을 다시 찾습니다. - 생성자 주입, 다른 공급자 메소드?

다시 모듈에 제공되므로 getNetworkCache에 도달하고 또 다른 종속성이 필요하다는 것을 다시 한번 알게됩니다.

HttpUrl (getEndpoint)과 같이 다른 종속성이 필요없는 개체에 도달 할 때까지이 동작이 계속됩니다.

이 모든 작업을 완료하면 OkHttpClient을 생성 할 수 있습니다.

나는 당신이 당신의 의존성 그래프에 사이클을 가질 수 없습니다 이유에서 이해하기 쉽게 생각 - 그것은 B에 따라 달라 BA에 의존하는 경우 당신은 객체 A를 만들 수 없습니다. 어떤 이상한 이유가 있다고 생각하면 getEndpoint이라는 메소드가 있는데 그 모듈의 OkHttpClient에 의존합니다. 이것은 효과가 없을 것입니다. 당신은 결코 끝까지 도달하지 못하는 원으로 들어갈 것입니다.

질문 : 필요한 입력을 얻기 위해 각 싱글 톤을 차례로 호출하지 않고 전체 종속성 그래프를 어떻게 사용합니까?

아니야. 싱글 톤을 얻으려면 모든 메소드를 호출해야합니다. 최소한 동일한 구성 요소/범위 내에서 제공됩니다. 그런 다음 구성 요소의 동일한 인스턴스를 유지하는 한 범위가 지정된 종속성은 항상 동일한 인스턴스를 반환합니다. 단검이이를 확인합니다. 어떤 이유로 든 구성 요소를 없애거나 다시 작성하면 종속성이 동일한 인스턴스가되지 않습니다. 더 많은 정보 here. 사실 모든 스코프에 적용됩니다. 뿐만 아니라 @Singleton s.

그러나 내가 할 수있는 한 당신이 올바르게하고 있다고 말할 수 있습니다. 응용 프로그램을 만들 때 구성 요소를 만들고 캐시합니다. 그 후에는 항상 component() 메서드를 사용할 때마다 항상 동일한 구성 요소를 반환하며 범위가 지정된 종속성은 항상 동일합니다.

+0

나는 그것을 알아 냈고 그것을 사용하고있다. Spring에서 의존성 삽입을 수행함에 따라, 생각 프로세스와 구현을 통해 스스로 설정해야하는 필요성을 변경하는 것이 어려웠습니다. Dagger가 전화 한 번으로 너무 많은 일을하는 것은 정말 멋지다. 나는 완전한 대답을위한 upvote를 주었다. –