简体   繁体   English

Dagger 2:在构造函数中注入接口

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

I'm trying to learn dagger 2 but I'm confused in injecting of constructor with interface.我正在尝试学习匕首 2,但我对使用接口注入构造函数感到困惑。 This is my below code:这是我下面的代码:

MainActivity.java 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 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) ;
}
}

This is the Module :这是模块

@Module
public class PresenterModule {

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

And this is the Component这是组件

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

When I run the code it shows me this error:当我运行代码时,它显示了这个错误:

Error:(15, 10) error: com.imennmn.hellodagger2example.MainView cannot be provided without an @Provides-annotated method.错误:(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 is injected at com.imennmn.hellodagger2example.simpleInjection.DataComponent.inject(activity) 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) 注入

My Question is how I can provide the interface MainView by inject it with dagger and bind the MainPresenter and MainActivity?我的问题是如何通过用匕首注入接口 MainView 并绑定 MainPresenter 和 MainActivity 来提供接口? Any help would be appreciated !任何帮助,将不胜感激 !

By following code: 通过以下代码:


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

You are telling dagger: "hey, whenever I ask you to inject MainPresenter , construct it using MainView " . 你在告诉匕首: “嘿,每当我要求你注入MainPresenter ,使用MainView构建它” But dagger complaints, because you haven't specified how exactly he should build/acquire MainView . 但是匕首投诉,因为你没有具体说明他应该如何构建/获取MainView

So, in your PresenterModule do this: 因此,在PresenterModule执行以下操作:


    @Module
    public class PresenterModule {

        MainView mainView;

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

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

    }

Then when building the component: 然后在构建组件时:


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

Your provideMainPresenter implicitly depends on a MainView . 您的provideMainPresenter隐式依赖于MainView Dagger has no way to get it. 匕首无法得到它。 You need to add a method to provide it: 您需要添加一个方法来提供它:

@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);
    }
}

Add abstract module with @Binds annotation, look at my impl of : AbstractTestSettingsFragmentModule.java 使用@Binds注释添加抽象模块,查看我的impl: AbstractTestSettingsFragmentModule.java

TestFragment.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 TestFragmentPresenterImpl.java

public class TestFragmentPresenterImpl implements TestFragmentContract.Presenter {

    @Inject
    public TestFragmentPresenterImpl(){
    }
}

AbstractTestSettingsFragmentModule.java AbstractTestSettingsFragmentModule.java

@Module
public abstract class AbstractTestSettingsFragmentModule {

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

}

ContributesModule.java ContributesModule.java

   @Module
    public abstract class ContributesModule {

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

AppComponent.java 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();

    }

}

You can use Assisted Injection with Dagger: https://dagger.dev/dev-guide/assisted-injection.html你可以使用 Dagger 的辅助注入: https://dagger.dev/dev-guide/assisted-injection.html

Assisted injection is a dependency injection (DI) pattern that is used to construct an object where some parameters may be provided by the DI framework and others must be passed in at creation time (aka “assisted”) by the user.辅助注入是一种依赖注入 (DI) 模式,用于构建 object,其中一些参数可能由 DI 框架提供,而其他参数必须在创建时由用户传入(也称为“辅助”)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM