我有一个注入Presenter的MainActivity,presenter对象注入了交互器,而者intector对象注入了APIHelper。 MainModule中有presenter,interactor和APIHelper的所有提供者。
@Module
public class MainActivityModule {
private final MainActivity activity;
//Context context;
public MainActivityModule (MainActivity activity) {
this.activity = activity;
}
@Provides
@Singleton
public MainViewPresenter providesMainPresenter(){
return new MainPresenterImpl(activity);
}
@Provides
@Singleton
ListingInteractor providesInteractor( ){
return new ListingInteractorImpl(activity);
}
@Provides
@Singleton
ApiHelper providesAPI( ){
return new ApiHelper(activity);
}
}
我在MainActivity中注入了组件,如:
DaggerMainActivityComponent.builder()
.mainActivityModule(new MainActivityModule(MainActivity.this))
.build().inject(this);
在我的Presenter实现中,我有像:
这样的交互器public class MainPresenterImpl implements MainViewPresenter {
Context context;
private MainView mainView;
// @Inject
ListingInteractor interactor; //here i get null interactor
MyScrollListener scrollListener;
public MainPresenterImpl(MainActivity activity) {
this.context = activity;
this.mainView = activity;
}
@Override
public void getCatFacts() {
interactor.getFacts();
}
我的交互器实现类有API助手,其构造函数需要上下文
public class ListingInteractorImpl implements ListingInteractor{
private Context context;
@Inject
private APIHelper; // getting null APIHelper
public ListingInteractorImpl(Context context) {
this.context = context;
}
我的组件界面如下:
@Component(modules={MainActivityModule.class})
@Singleton
public interface MainActivityComponent {
void inject(MainActivity mainActivity);
/*void inject(MainPresenterImpl presenter);*/
MainViewPresenter getMainPresenter();
ListingInteractor getInteractor();
ApiHelper getHelper();
}
但是只有Presenter对象在MainActivity中创建,演示者中的所有其他对象包括interactor,APIHelper都是null。根据dagger,它应该解析所有依赖项。
答案 0 :(得分:0)
更改MainPresenterImpl
& ListingInteractorImpl
构造函数在@Inject
之后跟随并在它们之前:
@Inject
public MainPresenterImpl(MainActivity activity, ListingInteractor interactor) {...}
@Inject
public ListingInteractorImpl(Context context, APIHelper helper) {...}
然后在你的模块实现中:
@Provides
@Singleton
public MainViewPresenter providesMainPresenter(ListingInteractor interactor){
return new MainPresenterImpl(activity, interactor);
}
@Provides
@Singleton
ListingInteractor providesInteractor(APIHelper helper){
return new ListingInteractorImpl(activity, helper);
}
答案 1 :(得分:0)
public class MainPresenterImpl implements MainViewPresenter {
// ... other fields ...
@Inject
ListingInteractor interactor;
public MainPresenterImpl(MainActivity activity) {
this.context = activity;
this.mainView = activity;
}
}
匕首这......没什么。您为场注入标记了一些字段(ListingInteractor
),但除非您手动调用组件以注入对象,否则不会发生任何事情。应该为活动和片段保留字段注入,您不能在构造函数中添加参数,而不是为普通类添加。
@Provides
@Singleton
MainViewPresenter providesMainPresenter(){
return new MainPresenterImpl(activity);
}
不要让Dagger为你创建MainPresenterImpl
,而是自己拨打new MainPresenterImpl()
,只传递活动。由于没有MainPresenterImpl.interactor
的来电,因此会null
。您没有使用现场注入,您自己调用构造函数而您没有分配字段。
应该为需要进一步设置的对象保留在模块中手动创建对象,例如Retrofit
或OkHttp
及其构建器。
如果您希望设置字段,可以使用字段注入并使用Component注册对象(那些inject(FieldInjectableClass clazz)
方法)并在代码中撒component.inject(myObject)
,这将是非常糟糕的这个想法,因为你最终写了很多你不需要的样板。
更合理的方法是将依赖项移动到它们所属的构造函数。
public MainPresenterImpl(MainActivity activity, ListingInteractor interactor) { /* ... */ }
如果您对另一个类有依赖关系,为什么不这样声明呢?但是这仍然留下了你自己创造对象的样板,而不是让Dagger完成它的工作。
这就是为什么你应该使用 构造函数注入 的原因。顾名思义,它是关于构造函数的。只需添加@Inject
注释:
@Inject // marked for constructor injection!
public MainPresenterImpl(MainActivity activity, ListingInteractor interactor) { /* ... */ }
现在Dagger知道你的班级的这个入口点并且可以创建它。
让dagger处理事情你可以将@Singleton
范围添加到类本身(注释类,而不是构造函数),只删除它的@Provides
方法(不需要提供)模块中的方法,用于不需要进一步设置的对象),但由于您将实现绑定到接口,您仍需要指定要绑定到接口的类。
@Provides
@Singleton
MainViewPresenter providesMainPresenter(MainPresenterImpl implementation){
return implementation;
}
由于Dagger可以使用构造函数注入创建MainPresenterImpl
,因此您可以返回接口的实现,并且在构造函数签名发生更改时无需更新任何代码,因为Dagger将相应地调整类实例化。
如何使用构造函数注入并将实现绑定到接口。如上所述,我建议高度阅读基础知识。确保你了解Dagger的作用及其运作方式。请务必了解字段和构造函数注入之间的区别,或何时使用模块。
你现在投入学习Dagger的时间意味着更少的调试和错误。
如果你的模块是抽象的或接口,你也可以使用@Binds
方法,Dagger只会生成上面的样板代码。
@Binds
@Singleton
MainViewPresenter providesMainPresenter(MainPresenterImpl implementation);