android - 带有 Dagger 2 和普通元素的 MVP

标签 android mvp dagger-2 dagger

我在 Dagger 2 中使用 MVP 模式。

我的项目有两个使用公共(public)存储库的功能。这意味着我必须注入(inject)该存储库两次,每个功能一次。但是当它尝试执行此操作时,我收到此错误:“...存储库已绑定(bind)多次”

我发现可以使用@Named解决这个问题。因此,我将其添加到我的模块中,但现在我收到一个新错误“...如果没有 @Provides-annotated 方法,则无法提供存储库。”

我想我必须在项目的其他地方添加这个 @Named 才能使其正常工作,因为我得到了一些解释这一点的链接(例如 multiple instance of same object with named )。问题是我对这一切都很陌生,无法找到在项目架构中的其他位置添加此 @Names 的位置。

所以,我实际上收到了这个错误“...如果没有@Provides注释的方法就无法提供存储库。”

我的项目结构如下。

==== 包含这三个类的根包:

应用程序类别

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

ApplicationComponent 类

@Singleton
@Component(modules = {ApplicationModule.class, PollutionApiModule.class, PollutionLevelsModule.class, DonutModule.class})
public interface ApplicationComponent {

    void injectPollutionLevels(PollutionLevelsFragment target);
    void injectDonut(DonutFragment target);

}

ApplicationModule 类

@Module
public class ApplicationModule {
    private Application application;
    public ApplicationModule(Application application) {
        this.application = application;
    }

    @Provides
    @Singleton
    public Context provideContext() {
        return application;
    }
}

==== 污染级别包,包含 Dagger 模块,该包是 MVP 结构(Fragment、Model、Module、Presenter...),并且与从以下位置获取数据的单个功能相关我的公共(public)存储库。此功能的目的是将我的数据显示为文本:

PollutionLevelModule 类,您可以在这里看到我尝试添加 @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);
    }
}

此包包含一个 fragment ,我在 onActivityCreated() 中注入(inject)存储库。在这里,我调用了在我的 App 类(我在上面向您展示的类)中实现的方法 injectPollutionLevels() :

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    ((App) getActivity().getApplication()).getComponent().injectPollutionLevels(this);
}

==== 一个 donut 包,包含 Dagger 模块,该包是 MVP 结构(Fragment、Model、Module、Presenter...),并且与从以下位置获取数据的单个功能相关我的公共(public)存储库。此功能的目的是将我的数据显示为图表:

DonutModule 类,您可以在这里看到我尝试添加 @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);
    }
}

此包包含一个 fragment ,我在 onActivityCreated() 中注入(inject)存储库。在这里,我调用了在我的 App 类(我在上面向您展示的类)中实现的方法 injectDonut() :

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

这是我的架构的屏幕截图,如果它可以帮助您更好地指出如何解决这个问题。如果您需要更多源代码,请告诉我。谢谢。

enter image description here

最佳答案

只要提供@Named Repository,还需要索取@Named Repository

@Provides
public DonutFragmentMVP.Model provideDonutFragmentModel(@Named("donutRepo") Repository repository) {
    return new DonutModel(repository);
}

关于android - 带有 Dagger 2 和普通元素的 MVP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43602016/

相关文章:

android - Dagger 2 : cannot be provided without an @Inject constructor or from an @Provides-annotated method

Android 以当前方向开始布局,之后禁用旋转

c# - MVP 三元组之间的通信

android - 垂直和倒置的SeekBar

android - Realm 、RxJava、asObservable() 和 doOnUnsubscribe()

ASP.NET MVP 与 ASP.NET MVC

android - 无法使用 Dagger 2 运行 Kotlin

java - Dagger 2 : Multiple entries with same key

android - 在 Eclipse 中调试 Android - 'step-into' 跳转到错误的行号

android - 来自 Android Play Places 的 PLACES_API_INVALID_APP 错误