Android Studio 2.2.2
我有一个 NewsListModelImp
类,它是 MVP 中的模型。
我想将改造服务注入(inject)到模型中。但是,由于 NewsListModelImp
不包含对上下文或 Activity 的任何引用,因此我无法调用 getApplication()
。如果你在一个 Activity 或 fragment 中,你会做什么。我不想在 NewsListModeImp
的构造函数中传递任何上下文或 Activity ,因为它们必须来自演示者,我想避免那里有任何 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);
}
}
我的应用组件
@Singleton
@Component(modules = {RetrofitModule.class})
public interface AppComponent {
void inject(NewsListModelImp target);
}
非常感谢您的任何建议,
最佳答案
Dagger-2
反复工作。因此,如果在 Activity
(或 Fragment
)内部对象被注入(inject),并且它的构造函数被正确地注解为 @Inject
注释,构造函数的参数也将被注入(inject).
假设在您要注入(inject)的应用程序中:
@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;
}
}
然后一切都将被正确注入(inject)。
为什么参数应该作为构造函数的参数传递给类?这样的设计模式符合SOLID principles
.对象依赖项被注入(inject)到对象中,而不是在对象内部创建,这样的代码很容易测试(在测试中,依赖项可以被替换,即被 Mock
替换)
额外信息:
可以注入(inject)实现特定接口(interface)的对象。描述了这种技术here .在您的情况下,NyTimesPresenter
可以具有 NewsListModelContract
,因为它是依赖项而不是 NewsListModelImp
。为此,请将另一个模块添加到您的 AppComponent
:
@Singleton
@Component(
modules = {
RetrofitModule.class,
AppModule.class
})
public interface AppComponent {
AppComponent
提供具体类实现接口(interface)的方法应该如下所示:
@Singleton
@Module
public abstract class AppModule {
@Binds
public abstract NewsListModelContract provideNewsListModelContract(NewsListModelImp newsListModelImp);
}
NyTimesPresenter
的实现应该改变(只是用它实现的接口(interface)替换具体类):
public class NyTimesPresenter {
NewsListModelContract newsListModel;
@Inject
public NyTimesPresenter(NewsListModelContract newsListModel) {
this.newsListModel = newsListModel;
}
}
关于android - 如何使用 dagger2 注入(inject)没有任何 Activity 或 fragment 的 java 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40166022/