Android Studio 2.2.2
我有一个NewsListModelImp
类,它是MVP中的模型。
我想将改装服务注入模型中。但是,由于NewsListModelImp
不包含对上下文或活动的任何引用,因此我无法调用getApplication()
。如果您在活动或片段中,您将采取以下措施。我不想在NewsListModeImp
的构造函数中传递任何上下文或活动,因为它必须来自演示者,我想避免那里的任何android东西。
public class NewsListModelImp implements NewsListModelContract {
@Inject
NYTimesSearchService mNYTimesSearchService;
public NewsListModelImp() {
((NYTimesSearchApplication)getApplication()).getAppComponent().inject(this);
}
}
我的申请类
public class NYTimesSearchApplication extends Application {
private AppComponent mAppComponent;
public void onCreate() {
super.onCreate();
/* Setup dependency injection */
createAppComponent();
}
private void createAppComponent() {
mAppComponent = DaggerAppComponent
.builder()
.retrofitModule(new RetrofitModule())
.build();
}
public AppComponent getAppComponent() {
return mAppComponent;
}
}
我提供的模块
@Module
public class RetrofitModule {
private Retrofit retrofit() {
return new Retrofit
.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
@Provides
@Singleton
public NYTimesSearchService providesNYTimesSearch() {
return retrofit().create(NYTimesSearchService.class);
}
}
我的App组件
@Singleton
@Component(modules = {RetrofitModule.class})
public interface AppComponent {
void inject(NewsListModelImp target);
}
非常感谢任何建议,
答案 0 :(得分:5)
Dagger-2
重新开始工作。因此,如果注入了Activity
(或Fragment
)对象,并且使用@Inject
注释正确地注释了它的构造函数,那么构造函数的参数也将被注入。 / p>
假设您想要注入的应用程序内部:
@Inject NyTimesPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
((NYTimesSearchApplication) getApplication()).getAppComponent().inject(this);
}
NyTimesPresenter
的构造函数必须使用@Inject
注释:
public class NyTimesPresenter {
NewsListModelImp newsListModel;
@Inject
public NyTimesPresenter(NewsListModelImp newsListModel) {
this.newsListModel = newsListModel;
}
}
NewsListModelImp
构造函数也必须使用@Inject
注释:
public class NewsListModelImp implements NewsListModelContract {
NYTimesSearchService mNYTimesSearchService;
@Inject
public NewsListModelImp(NYTimesSearchService nYTimesSearchService) {
this.mNYTimesSearchService = nYTimesSearchService;
}
}
然后一切都会正确注入。
为什么参数应该作为构造函数传递给类'参数?这种设计模式符合SOLID principles
。对象依赖项被注入到对象中而不是在其中创建,并且这样的代码很容易测试(在测试中,依赖项可以被替换,即Mock
' s)
额外信息:
可以注入实现特定接口的对象。描述了这种技术here。在您的情况下,NyTimesPresenter
可以NewsListModelContract
作为依赖,而不是NewsListModelImp
。为此,请在AppComponent
添加另一个模块:
@Singleton
@Component(
modules = {
RetrofitModule.class,
AppModule.class
})
public interface AppComponent {
提供具体类实现接口的 AppComponent
方法应如下所示:
@Singleton
@Module
public abstract class AppModule {
@Binds
public abstract NewsListModelContract provideNewsListModelContract(NewsListModelImp newsListModelImp);
}
NyTimesPresenter
的实现应该改变(只是用它实现的接口替换具体类):
public class NyTimesPresenter {
NewsListModelContract newsListModel;
@Inject
public NyTimesPresenter(NewsListModelContract newsListModel) {
this.newsListModel = newsListModel;
}
}