Dagger 2 和普通对象的 MVP
MVP with Dagger 2 and common object
我在 Dagger 2 中使用 MVP 模式。
我的项目有两个使用公共存储库的功能。这意味着我必须将此存储库注入两次,每个功能一次。但是当它试图这样做时,我得到了这个错误:"...Repository is bound multiple times"
我发现使用 @Named
可以解决这个问题。所以我在我的模块中添加了它,但现在我收到了一个新错误 "...没有 @Provides-annotated
方法就无法提供存储库。"
我想我必须在项目的其他地方添加这个 @Named
才能使其正常工作,因为我得到了一些 link 解释(比如这个 )。这个问题我对这一切都很陌生,无法在我的项目架构的其他地方找到添加这个 @Names
的地方。
所以,我实际上遇到了这个错误 “...如果没有 @Provides-annotated 方法,则无法提供存储库。”
我的项目结构如下。
==== 一个 根包 包含这三个 classes :
应用class
public class App extends Application {
private ApplicationComponent component;
@Override
public void onCreate() {
super.onCreate();
final String AUTH_TOKEN = getResources().getString(R.string.aqicn_token);
final String BASE_URL = getResources().getString(R.string.aqicn_api_base_url);
component = DaggerApplicationComponent.builder()
.applicationModule(new ApplicationModule(this))
.pollutionApiModule(new PollutionApiModule(BASE_URL))
.pollutionLevelsModule(new PollutionLevelsModule())
.build();
}
public ApplicationComponent getComponent() {
return component;
}
}
应用组件class
@Singleton
@Component(modules = {ApplicationModule.class, PollutionApiModule.class, PollutionLevelsModule.class, DonutModule.class})
public interface ApplicationComponent {
void injectPollutionLevels(PollutionLevelsFragment target);
void injectDonut(DonutFragment target);
}
应用模块class
@Module
public class ApplicationModule {
private Application application;
public ApplicationModule(Application application) {
this.application = application;
}
@Provides
@Singleton
public Context provideContext() {
return application;
}
}
==== 一个包含 Dagger 模块的 pollutionlevels 包,这个包是 MVP 结构的(Fragment、Model、Module、Presenter...)并且与单个从我的公共存储库获取数据的功能。此功能的目的是将我的数据显示为文本:
PollutionLevelModule class,你可以在这里看到我试图添加 @Name 注释来解决我的问题:
@Module
public class PollutionLevelsModule {
@Provides
public PollutionLevelsFragmentMVP.Presenter providePollutionLevelsFragmentPresenter(PollutionLevelsFragmentMVP.Model pollutionLevelsModel) {
return new PollutionLevelsPresenter(pollutionLevelsModel);
}
@Provides
public PollutionLevelsFragmentMVP.Model providePollutionLevelsFragmentModel(Repository repository) {
return new PollutionLevelsModel(repository);
}
@Singleton
@Provides
@Named("levelsRepo")
public Repository provideRepo(PollutionApiService pollutionApiService) {
return new CommonRepository(pollutionApiService);
}
}
这个包包含一个片段,我在其中注入存储库 onActivityCreated()
。在这里,我调用在我的 App class 中实现的方法 injectPollutionLevels()
(我在上面向您展示的 class):
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
((App) getActivity().getApplication()).getComponent().injectPollutionLevels(this);
}
==== 一个包含 Dagger 模块的甜甜圈包,这个包是 MVP 结构的(片段,模型,模块,Presenter ...)并且与单个相关从我的公共存储库获取数据的功能。此功能的目的是将我的数据显示为图表:
DonutModule class,你可以在这里看到我试图添加@Name注解来解决我的问题:
@Module
public class DonutModule {
@Provides
public DonutFragmentMVP.Presenter providedDonutFragmentPresenter(DonutFragmentMVP.Model donutModel) {
return new DonutPresenter(donutModel);
}
@Provides
public DonutFragmentMVP.Model provideDonutFragmentModel(Repository repository) {
return new DonutModel(repository);
}
@Singleton
@Provides
@Named ("donutRepo")
public Repository provideRepo(PollutionApiService pollutionApiService) {
return new CommonRepository(pollutionApiService);
}
}
这个包包含一个片段,我在其中注入存储库 onActivityCreated()
。在这里,我调用在我的 App class 中实现的方法 injectDonut()
(我在上面向您展示的 class):
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
((App) getActivity().getApplication()).getComponent().injectDonut(this);
}
==== 包含我的存储库的通用包
public class CommonRepository implements Repository {
private PollutionApiService pollutionApiService;
public CommonRepository(PollutionApiService pollutionApiService) {
this.pollutionApiService = pollutionApiService;
}
@Override
public Observable<Aqicn> getDataFromNetwork(String city, String authToken) {
Observable<Aqicn> aqicn = pollutionApiService.getPollutionObservable(city, authToken);
return aqicn;
}
}
如果可以帮助您更好地指出如何解决此问题,这是我的架构的屏幕截图。如果您需要更多源代码,请告诉我。谢谢。
只要提供@Named Repository
,还需要索要@Named Repository
@Provides
public DonutFragmentMVP.Model provideDonutFragmentModel(@Named("donutRepo") Repository repository) {
return new DonutModel(repository);
}
我在 Dagger 2 中使用 MVP 模式。
我的项目有两个使用公共存储库的功能。这意味着我必须将此存储库注入两次,每个功能一次。但是当它试图这样做时,我得到了这个错误:"...Repository is bound multiple times"
我发现使用 @Named
可以解决这个问题。所以我在我的模块中添加了它,但现在我收到了一个新错误 "...没有 @Provides-annotated
方法就无法提供存储库。"
我想我必须在项目的其他地方添加这个 @Named
才能使其正常工作,因为我得到了一些 link 解释(比如这个 @Names
的地方。
所以,我实际上遇到了这个错误 “...如果没有 @Provides-annotated 方法,则无法提供存储库。”
我的项目结构如下。
==== 一个 根包 包含这三个 classes :
应用class
public class App extends Application {
private ApplicationComponent component;
@Override
public void onCreate() {
super.onCreate();
final String AUTH_TOKEN = getResources().getString(R.string.aqicn_token);
final String BASE_URL = getResources().getString(R.string.aqicn_api_base_url);
component = DaggerApplicationComponent.builder()
.applicationModule(new ApplicationModule(this))
.pollutionApiModule(new PollutionApiModule(BASE_URL))
.pollutionLevelsModule(new PollutionLevelsModule())
.build();
}
public ApplicationComponent getComponent() {
return component;
}
}
应用组件class
@Singleton
@Component(modules = {ApplicationModule.class, PollutionApiModule.class, PollutionLevelsModule.class, DonutModule.class})
public interface ApplicationComponent {
void injectPollutionLevels(PollutionLevelsFragment target);
void injectDonut(DonutFragment target);
}
应用模块class
@Module
public class ApplicationModule {
private Application application;
public ApplicationModule(Application application) {
this.application = application;
}
@Provides
@Singleton
public Context provideContext() {
return application;
}
}
==== 一个包含 Dagger 模块的 pollutionlevels 包,这个包是 MVP 结构的(Fragment、Model、Module、Presenter...)并且与单个从我的公共存储库获取数据的功能。此功能的目的是将我的数据显示为文本:
PollutionLevelModule class,你可以在这里看到我试图添加 @Name 注释来解决我的问题:
@Module
public class PollutionLevelsModule {
@Provides
public PollutionLevelsFragmentMVP.Presenter providePollutionLevelsFragmentPresenter(PollutionLevelsFragmentMVP.Model pollutionLevelsModel) {
return new PollutionLevelsPresenter(pollutionLevelsModel);
}
@Provides
public PollutionLevelsFragmentMVP.Model providePollutionLevelsFragmentModel(Repository repository) {
return new PollutionLevelsModel(repository);
}
@Singleton
@Provides
@Named("levelsRepo")
public Repository provideRepo(PollutionApiService pollutionApiService) {
return new CommonRepository(pollutionApiService);
}
}
这个包包含一个片段,我在其中注入存储库 onActivityCreated()
。在这里,我调用在我的 App class 中实现的方法 injectPollutionLevels()
(我在上面向您展示的 class):
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
((App) getActivity().getApplication()).getComponent().injectPollutionLevels(this);
}
==== 一个包含 Dagger 模块的甜甜圈包,这个包是 MVP 结构的(片段,模型,模块,Presenter ...)并且与单个相关从我的公共存储库获取数据的功能。此功能的目的是将我的数据显示为图表:
DonutModule class,你可以在这里看到我试图添加@Name注解来解决我的问题:
@Module
public class DonutModule {
@Provides
public DonutFragmentMVP.Presenter providedDonutFragmentPresenter(DonutFragmentMVP.Model donutModel) {
return new DonutPresenter(donutModel);
}
@Provides
public DonutFragmentMVP.Model provideDonutFragmentModel(Repository repository) {
return new DonutModel(repository);
}
@Singleton
@Provides
@Named ("donutRepo")
public Repository provideRepo(PollutionApiService pollutionApiService) {
return new CommonRepository(pollutionApiService);
}
}
这个包包含一个片段,我在其中注入存储库 onActivityCreated()
。在这里,我调用在我的 App class 中实现的方法 injectDonut()
(我在上面向您展示的 class):
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
((App) getActivity().getApplication()).getComponent().injectDonut(this);
}
==== 包含我的存储库的通用包
public class CommonRepository implements Repository {
private PollutionApiService pollutionApiService;
public CommonRepository(PollutionApiService pollutionApiService) {
this.pollutionApiService = pollutionApiService;
}
@Override
public Observable<Aqicn> getDataFromNetwork(String city, String authToken) {
Observable<Aqicn> aqicn = pollutionApiService.getPollutionObservable(city, authToken);
return aqicn;
}
}
如果可以帮助您更好地指出如何解决此问题,这是我的架构的屏幕截图。如果您需要更多源代码,请告诉我。谢谢。
只要提供@Named Repository
,还需要索要@Named Repository
@Provides
public DonutFragmentMVP.Model provideDonutFragmentModel(@Named("donutRepo") Repository repository) {
return new DonutModel(repository);
}