2015-04-23 73 views
7

我有一個簡單的Dagger 2測試設置,基於http://konmik.github.io/snorkeling-with-dagger-2.html。 它注入一個PreferenceLogger,輸出所有首選項。在注入的類中,我可以@Inject更多的類。匕首2和界面實現

public class MainActivity extends Activity { 
    @Inject PreferencesLogger logger; 
    @Inject MainPresenter presenter; 

    @Override protected void onCreate(Bundle savedInstanceState) { 
    MyApplication.getComponent().inject(this); 
    presenter.doStuff(); 
     logger.log(this); 
    } 
} 


public class PreferencesLogger { 

    @Inject OkHttpClient client; 
    @Inject public PreferencesLogger() {} 

    public void log(Contect context) { 
    // this.client is available 
    } 
} 

當我運行這個,記錄器被設置,並在PreferencesLogger.log內OkHttpClient被正確設置。 因此,此示例按預期工作。 現在我正在嘗試獲得MVP結構。 有一個MainPresenter接口和一個實現。在MainActivity中,我設置了一個:

@Inject MainPresenter presenter; 

所以我可以使用替代(調試或測試)實現切換此MainPresenter。當然,現在我需要一個模塊來指定我想要使用的實現。

public interface MainPresenter { 
    void doStuff(); 
} 

public class MainPresenterImpl implements MainPresenter { 

    @Inject OkHttpClient client; 

    public MainPresenterImpl() {} 

    @Override public void doStuff() { 
    // this.client is not available  
    } 
} 


@Module public class MainActivityModule { 
    @Provides MainPresenter provideMainPresenter() { 
     return new MainPresenterImpl(); 
    } 
} 

現在出現OkHttpClient不再被注入的問題。當然,我可以改變模塊接受參數OkHttpClient,但我不認爲這是建議的方式來做到這一點。 MainPresenterImpl無法正確注入的原因是什麼?

+0

我在這裏提出一個相關的問題:http://stackoverflow.com/questions/30555285/dagger2-injecting-implementation-classes-with-component – EpicPandaForce

+0

看看這篇文章和示例項目,該項目可能會有所幫助: https://medium.com/@m_mirhoseini/yet-another-mvp-article-part-1-lets-get-to-know-the-project-d3fd553b3e21#.6y9ze7e55 –

回答

4

與構造函數注入不同,在@Provides方法中構造的@Inject註釋的依賴項字段不能被自動注入。能夠注入字段需要一個在其模塊中提供字段類型的組件,而在提供者方法本身中,此類實現不可用。

presenter字段在MainActivity注入,所發生的一切是提供方法被調用,presenter設置爲它的返回值。在你的例子中,無參數構造函數沒有進行初始化,提供者方法也沒有,因此不進行初始化。

然而,提供者方法可以通過其參數訪問模塊中提供的其他類型的實例。我認爲在提供者方法中使用參數實際上是「注入」所提供類型的依賴關係的建議(甚至是唯一的)方式,因爲它明確指出它們是模塊內的依賴關係,這允許Dagger在編譯時拋出一個錯誤 - 如果他們不能得到滿足的話。

它之所以目前不拋出一個錯誤是因爲MainPresenterImpl可能得到它OkHttpClient依賴性滿意,如果MainPresenterImpl,而不是MainPresenter某處用於注射的目標。 Dagger無法爲接口類型創建成員注入方法,因爲作爲接口,它不能注入字段,也不會自動注入實現類型的字段,因爲它只是提供任何提供者方法回報。

4

您可以使用構造函數注入注入您的MainPresenterImpl

/* unscoped */ 
public class MainPresenterImpl implements MainPresenter { 

    @Inject 
    OkHttpClient client; 

    @Inject 
    public MainPresenterImpl() { 
    } 

    @Override public void doStuff() { 
     // this.client is now available! :) 
    } 
} 


@Module 
public class AppModule { 
    private MyApplication application; 

    public AppModule(MyApplication application) { 
     this.application = application; 
    } 

    @Provides 
    /* unscoped */ 
    public MyApplication application() { 
     return application; 
    } 
} 

@Module 
public abstract class MainActivityModule { 
    @Binds public abstract MainPresenter mainPresenter(MainPresenterImpl mainPresenterImpl); 
}