BRDroid
BRDroid

Reputation: 4388

how to handle dependency cycle dagger 2

I have two classes PdfTicketStorage and OfflineHelper they both depend on each other.

OfflineHelper class requires PdfTicketStorage to send data to firebase

class OfflineHelper @Inject constructor(
    private val app: App,
    private val settings: Settings,
    private val pdfTicketStorage: PdfTicketStorage,
) {
       private fun postPrintedTicket(offlineData: OfflineData) {
      //SENDS DATA TO FIREBASE
        val offlinePrintedTicketInfo = gson.fromJson(offlineData.requestInfoJson, OfflinePrintedTicketInfo::class.java)
        pdfTicketStorage.store(offlinePrintedTicketInfo.pdfTicketFilePath, offlinePrintedTicketInfo.pdfTicketContent)
    }

    fun saveOfflineDataWithPdf() {
      //save data to database
    }
}

PdfTicketStorage requires offlineHelper to save data in the database

public class PdfTicketStorage {

    private final String cloudStorageBucket;
    private final OfflineHelper offlineHelper;

    public PdfTicketStorage(String cloudStorageBucket, OfflineHelper offlineHelper) {
        this.cloudStorageBucket = cloudStorageBucket;
        this.offlineHelper = offlineHelper;
    }

     public Single<String>  storeTest(final String filePath, final byte[] fileContents, final String fuelOrderId) {
            offlineHelper.saveOfflineDataWithPdf();
            return Single.just("");
      
    }
}

As both are interdependent how can resolve the dependency cycle

error i get

[Dagger/DependencyCycle] Found a dependency cycle:
public interface AppComponent {
       ^
      com.xx.xxx.clean.offline.OfflineHelper is injected at
          com.xx.xxx.injection.modules.ServiceModule.providePdfTicketStorage(…, offlineHelper)
      com.xx.xxx.printing.storage.PdfTicketStorage is injected at
          com.xx.xxx.clean.offline.OfflineHelper(…, pdfTicketStorage, …)
      com.xx.xxx.clean.offline.OfflineHelper is injected at
          com.xx.xxx.activities.MainActivity.offlineHelper
      com.xx.xxx.activities.MainActivity is injected at
          com.xxx.xx.injection.components.ActivityComponent.inject(com.xx.xxx.activities.MainActivity) [com.xx.xxx.injection.components.AppComponent → com.xx.xxx.injection.components.ActivityComponent]

ServiceModule

  @Provides @PerApp
    public PdfTicketStorage providePdfTicketStorage(App app, OfflineHelper offlineHelper) {
        return new PdfTicketStorage(app.getString(R.string.cloud_storage_bucket), offlineHelper);
    }

Could you suggest any alternatives to fix this please

thanks R

Upvotes: 1

Views: 270

Answers (1)

Ruokki
Ruokki

Reputation: 957

You should use Lazy

public class PdfTicketStorage {

    private final String cloudStorageBucket;
    private final Lazy<OfflineHelper> offlineHelper;

    public PdfTicketStorage(String cloudStorageBucket, Lazy<OfflineHelper> offlineHelper) {
        this.cloudStorageBucket = cloudStorageBucket;
        this.offlineHelper = offlineHelper;
    }

     public Single<String>  storeTest(final String filePath, final byte[] fileContents, final String fuelOrderId) {
            offlineHelper.get().saveOfflineDataWithPdf();
            return Single.just("");
      
    }
}

The inconvenient is Lazy Injection directly impact parameter of your constructeur. But if it's fine for you you can use it

Upvotes: 2

Related Questions