首页 > 解决方案 > Dagger 2 依赖图被绑定多次

问题描述

我已经查看了有关此问题的多个帖子,但建议的解决方案似乎都没有解决我的问题。我看过的一些帖子如下

  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 依赖于依赖于 Android Context 的 NotificationManager,而 Map 在这种情况下 NotificationBuilder 是一个 POJO,它接受 Context 作为构造函数参数。

我们有一个通用的 AppModule,其中定义了所有依赖项,这就是它的设置方式

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

PushServiceModule注入依赖项如下:

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

通知管理器模块

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

问题

当我尝试编译项目时,这是我得到的错误

/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

期望的行为

我希望能够注入其中NotificationManagerCreateLoggedOutTask然后将注入AppSignOutHelper. 我做错了什么?

标签: javaandroiddependency-injectiondagger-2

解决方案


推荐阅读