Граф зависимостей Dagger 2 связан несколько раз - PullRequest
0 голосов
/ 10 ноября 2019

Я просмотрел несколько сообщений на эту тему, но ни одно из предложенных решений, похоже, не решило мою проблему. Некоторые из постов, которые я просмотрел, приведены ниже

  1. ошибка: [Dagger / DuplicateBindings] com.example.StartRouter связан несколько раз?

  2. График зависимостей модуля Dagger 2: связан несколько раз

  3. Dagger2 Ошибка при внедрении в классе, который вводит

Но я не знаю, что я делаю неправильно. Это моя установка. Я внедряю класс с именем NotificationManager в два отдельных класса. Примеры приведены ниже

1

class PushJobIntentService extends JobIntentService {
    @Inject
    PushService pushService

    @Override
    public void onCreate()
    {
        AndroidInjection.inject(this);
        super.onCreate();
    }

    @Override
    protected void onHandleWork(@NonNull Intent intent)
    {
        .. Do Work . . . 
    }
}

PushService - это простой POJO, граф зависимостей экземпляра которого выглядит следующим образом. NotificationManager внедряется в PushService через конструктор.

PushService -> NotificationManager -> (Context, Map <String, NotificationBuilder>)

В этом примере PushService зависит от NotificationManager, который зависит от контекста Android, и от Map, в этом случае NotificationBuilder является POJO, который принимает Context в качестве аргумента конструктора.

У нас есть общий AppModule, в котором определены все зависимости, и вот как он настроен

@ContributesAndroidInjector(modules = {PushServiceModule.class})
abstract PushJobIntentService contributePushJobIntentServiceInjector();

PushServiceModule внедряет зависимости следующим образом:

@Module(includes = {NotificationManagerModule.class})
public abstract class PushServiceModule
{
    . . . Dependenies of PushService . . . 
}

NotificationManagerModule

@Module()
public abstract class NotificationManagerModule
{
    @Provides
    static Map<String, NotificationBuilder> provideNotificationBuilders(Context context)
    {
        Map<String, NotificationBuilder> builders = new HashMap<>();
        builders.put("Key1",new NotificationBuilder(context, "Key1", "Text1"));
        return Collections.unModifiableMap(builders);
    }
}

2

Второй граф зависимостей выглядит следующим образом

AppSignOutHelper -> LoggedOutTask (Async Task) -> NotificationManager

Я пытаюсь внедрить NotificationManager в LoggedOutTask. AppSignOutHelper реализует SignOutHelper и определяется следующим образом:

/**
 * Binds the {@link AppSignOutHelper} instance to the shared {@link SignOutHelper} interface.
 */
@Binds
@Qualifier
abstract SignOutHelper bindSignOutHelper(AppSignOutHelper appSignOutHelper); 

ISSUE

Когда я пытаюсь скомпилировать проект, это ошибка, которую я получаю

/Users/username/sourcecode/android/app/src/main/java/com/myproject/mobile/dagger/AppComponent.java:50: warning: [Dagger/DuplicateBindings] com.myproject.android.notifications.NotificationManager is bound multiple times:
public interface AppComponent extends DomainComponent
       ^
      @Inject com.myproject.android.notifications.NotificationManager(android.content.Context, Map<String,com.myproject.android.notifications.NotificationBuilder>) [com.myproject.android.dagger.AppComponent]
      @Provides com.myproject.android.notifications.NotificationManager com.myproject.android.notifications.NotificationManagerModule.provideNotificationManager(android.content.Context, Map<String,com.myproject.android.notifications.NotificationBuilder>) [com.myproject.android.dagger.AppComponent → com.myproject.android.dagger.AppModule_ContributePushJobIntentServiceInjector.PushJobIntentServiceSubcomponent]
  This condition was never validated before, and will soon be an error. See https://dagger.dev/conflicting-inject.
      com.myproject.android.notifications.NotificationManager is injected at
          com.myproject.android.notifications.PushService( myproject.NotificationManager)
      com.myproject.android.notifications.PushService is injected at
          com.myproject.android.notifications.PushJobIntentService.pushService
      com.myproject.android.notifications.PushJobIntentService is injected at
          dagger.android.AndroidInjector.inject(T) [com.myproject.android.dagger.AppComponent → com.myproject.android.dagger.AppModule_ContributePushJobIntentServiceInjector.PushJobIntentServiceSubcomponent]
/Users/username/sourcecode/android/app/src/main/java/com/myproject/mobile/dagger/AppComponent.java:50: error: [Dagger/MissingBinding] java.util.Map<java.lang.String,com.myproject.android.notifications.NotificationBuilder> cannot be provided without an @Provides-annotated method.
public interface AppComponent extends DomainComponent
       ^
  A binding with matching key exists in component: com.myproject.android.dagger.AppModule_ContributePushJobIntentServiceInjector.PushJobIntentServiceSubcomponent
      java.util.Map<java.lang.String,com.myproject.android.notifications.NotificationBuilder> is injected at
          com.myproject.android.notifications.NotificationManager(…, notifBuilderMap)
      com.myproject.android.notifications.NotificationManager is injected at
          com.myproject.android.notifications.CreateLoggedOutNotificationTask(…, myproject.NotificationManager)
      javax.inject.Provider<com.myproject.android.notifications.CreateLoggedOutNotificationTask> is injected at
          com.myproject.android.AppSignOutHelper(…, loggedOutNotificationTask, …)
      com.myproject.android.AppSignOutHelper is injected at
          com.myproject.android.dagger.AppModule.bindSignOutHelper(appSignOutHelper)
     com.myproject.android.SignOutHelper is injected at
          com.myproject.android.dagger.DomainModule.provideSignOutHelper(…, optionalInstance)
      com.myproject.android.SignOutHelper is provided at
          com.myproject.android.dagger.DomainComponent.getSignOutHelper()
1 error
1 warning

Но если я не включу NotificationManagerModule в модуль PushServiceModule и оставлю его следующим образом:

@Module()
public abstract class PushServiceModule
{
    . . . Dependenies of PushService . . . 
}

Я получу следующую ошибку

/Users/username/sourcecode/android/app/src/main/java/com/myproject/mobile/dagger/AppComponent.java:50: error: [Dagger/MissingBinding] java.util.Map<java.lang.String,com.myproject.android.notifications.NotificationBuilder> cannot be provided without an @Provides-annotated method.
    public interface AppComponent extends DomainComponent
           ^
          java.util.Map<java.lang.String,com.myproject.android.notifications.NotificationBuilder> is injected at
              com.myproject.android.notifications.NotificationManager(…, notifBuilderMap)
          com.myproject.android.notifications.NotificationManager is injected at
              com.myproject.android.notifications.CreateLoggedOutNotificationTask(NotificationManager)
          javax.inject.Provider<com.myproject.android.notifications.CreateLoggedOutNotificationTask> is injected at
              com.myproject.android.AppSignOutHelper(…, loggedOutNotificationTask, …)
          com.myproject.android.AppSignOutHelper is injected at
              com.myproject.android.dagger.AppModule.bindSignOutHelper(appSignOutHelper)
           com.myproject.android.SignOutHelper is injected at
              com.myproject.android.dagger.DomainModule.provideSignOutHelper(…, optionalInstance)
          com.myproject.android.SignOutHelper is provided at
              com.myproject.android.dagger.DomainComponent.getSignOutHelper()
      The following other entry points also depend on it:
          dagger.android.AndroidInjector.inject(T) [com.myproject.android.dagger.AppComponent → com.myproject.android.dagger.AppModule_ContributePushJobIntentServiceInjector.PushJobIntentServiceSubcomponent]
    1 error

DESIREDПОВЕДЕНИЕ

Я хочу иметь возможность ввести NotificationManager в CreateLoggedOutTask, который, в свою очередь, будет введен в AppSignOutHelper. Что я делаю не так?

...