簡體   English   中英

Dagger 2:在構造函數中注入接口

[英]Dagger 2: inject an interface in a constructor

我正在嘗試學習匕首 2,但我對使用接口注入構造函數感到困惑。 這是我下面的代碼:

MainActivity.java

public class MainActivity extends AppCompatActivity implements MainView {

    // this keyword of request dependency . At compiling process, dagger will look at all of these annotations
    //to create the exact dependency

    @Inject MainPresenter mainPresenter ;
    TextView textView ;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = findViewById(R.id.textview) ;
        DaggerPresenterComponent.create().inject(this);
        textView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                mainPresenter.doThings(8555) ;
            }
        });

    }

    /**********************************/

    @Override
    public void invokeRandomViewMethod(String msg) {
        textView.setText(msg);
    }
}

MainPresenter.java

public class MainPresenter {

    private MainView mainView ;

    @Inject
    public MainPresenter(MainView mainView) {
        this.mainView = mainView;
    }

    public void doThings(int value){
        Random random = new Random();
        int rand= random.nextInt(value) ;
        if(mainView != null){
            mainView.invokeRandomViewMethod("You random number is "+rand);
        }
    }

public interface MainView {
    void invokeRandomViewMethod(String msg) ;
}
}

這是模塊

@Module
public class PresenterModule {

    @Provides
        // this is the method that will provide the dependancy
    MainPresenter provideMainPresenter(MainView mainView){
        return new MainPresenter(mainView);
    }
}

這是組件

@Component (modules = PresenterModule.class)
public interface PresenterComponent {
    void inject(MainActivity activity) ;
}

當我運行代碼時,它顯示了這個錯誤:

錯誤:(15, 10) 錯誤:com.imennmn.hellodagger2example.MainView 不能在沒有@Provides 注釋的方法的情況下提供。 com.imennmn.hellodagger2example.MainView is injected at com.imennmn.hellodagger2example.presenterInjection.PresenterModule.provideMainPresenter(mainView) com.imennmn.hellodagger2example.MainPresenter is injected at com.imennmn.hellodagger2example.MainActivity.mainPresenter com.imennmn.hellodagger2example.MainActivity在 com.imennmn.hellodagger2example.simpleInjection.DataComponent.inject(activity) 注入

我的問題是如何通過用匕首注入接口 MainView 並綁定 MainPresenter 和 MainActivity 來提供接口? 任何幫助,將不勝感激 !

通過以下代碼:


    MainPresenter provideMainPresenter(MainView mainView) {
        return new MainPresenter(mainView);
    }

你在告訴匕首: “嘿,每當我要求你注入MainPresenter ,使用MainView構建它” 但是匕首投訴,因為你沒有具體說明他應該如何構建/獲取MainView

因此,在PresenterModule執行以下操作:


    @Module
    public class PresenterModule {

        MainView mainView;

        public PresenterModule(MainView mainView) {
            this.mainView = mainView;
        }

        @Provides
        MainPresenter provideMainPresenter() {
            return new MainPresenter(mainView);
        }

    }

然后在構建組件時:


    DaggerPresenterComponent.builder()
                            .presenterModule(new PresenterModule(this))
                            .build();

您的provideMainPresenter隱式依賴於MainView 匕首無法得到它。 您需要添加一個方法來提供它:

@Module
public class PresenterModule {

    @Provides
    MainView provideMainView(){
        // Provide MainView here somehow so Dagger can use this to create a MainPresenter
    }

    @Provides
    // this is the method that will provide the dependancy
    MainPresenter provideMainPresenter(MainView mainView){
        return new MainPresenter(mainView);
    }
}

使用@Binds注釋添加抽象模塊,查看我的impl: AbstractTestSettingsFragmentModule.java

TestFragment.java

public class TestFragment extends Fragment{

    @Inject TestFragmentContract.Presenter mPresenter;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AndroidSupportInjection.inject(this);

    }

 }

TestFragmentPresenterImpl.java

public class TestFragmentPresenterImpl implements TestFragmentContract.Presenter {

    @Inject
    public TestFragmentPresenterImpl(){
    }
}

AbstractTestSettingsFragmentModule.java

@Module
public abstract class AbstractTestSettingsFragmentModule {

    @Binds
    @NonNull
    public abstract TestSettingsFragmentContract.Presenter testSettingsFragmentPresenterImpl(TestSettingsFragmentImpl presenter);

}

ContributesModule.java

   @Module
    public abstract class ContributesModule {

        @ContributesAndroidInjector(modules = {AbstractTestSettingsFragmentModule.class})
        abstract TestSettingsFragment testSettingsFragment();
    }

AppComponent.java

@Singleton
@Component(
        modules = {
                AndroidSupportInjectionModule.class,
                ContributesModule.class,
                AppModule.class,
              })
public interface AppComponent extends AndroidInjector<DaggerApplication> {

    void inject(TheApplication theApplication);

    @Override
    void inject(DaggerApplication instance);

    @Component.Builder
    interface Builder {

        @BindsInstance
        Builder application(Application application);

        AppComponent build();

    }

}

你可以使用 Dagger 的輔助注入: https://dagger.dev/dev-guide/assisted-injection.html

輔助注入是一種依賴注入 (DI) 模式,用於構建 object,其中一些參數可能由 DI 框架提供,而其他參數必須在創建時由用戶傳入(也稱為“輔助”)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM