Dagger: Best practices for using dagger within a library project?

Created on 29 Dec 2015  路  6Comments  路  Source: google/dagger

The scenario I am encountering is the following:

I have an AAR, Core, which contains core activities, and entities (and their DAO's), etc. that are shared across several other applications. Within this application I am leveraging Dagger to provide dependencies to activites, presenters, etc.

I have a specific application, let's call it Foo, that depends on Core. For instance, it displays the login screen provided to it by Core. However, I will also need Foo to have it's own activities, that are not defined in Core. Because of this, I'm thinking Foo will need it's own object graph, as well, so that I can inject the activities that are only defined within Foo itself.

My question is, what is the best way to provide the dependencies that the Core object graph normally provides to those activities within the Foo application?

I'm thinking of making Foo's application-level component depend on the Core application-level component, although that's a bit ugly because all of the dependencies would then have to be explicitly provided in the application component provided by Core?

documentation

Most helpful comment

@sahir

I have since moved on from that project (and company), but I will explain to the best of my memory. I don't have access to the source code, to post snippets, unfortunately, so bare with me! :)

Let's say I'm trying to build a Database-Access related object graph. In my library project, I would create a DatabaseComponent interface, and within it, specify ONLY the dependencies that the library project itself can satisfy all on it's own.

Within the library project, in order to actually compile the project, I ensure there are Stubbed-out modules that are able to provide the dependencies defined within the DatabaseComponent (I stub out the provide methods by either returning null, or by returning No-Oped objects).

Then, in my main project, I can create a MainProjectDatabaseComponent (or something named similarly), and have that interface extend from DatabaseComponent. Then, within the actual definition of MainProjectDatabaseComponent, I can define further dependencies that the Main Project has knowledge of, and can provide. In this example, it could be potential DAOs that are relevant to models in the main project.

Then, within the main project, I provide the REAL modules, that can satisfy all dependencies listed in the MainProjectDatabaseComponent. And, since MainProjectDatabaseComponent extends DatabaseComponent, these modules would have to satisfy those dependencies as well.

All 6 comments

As of now, just to give a bit more information, the solution I came up with, was as follows:

My Foo application-level component actually extends the Core application-level component (via interface extension), and the Foo application is responsible for building that component, and has core modules registered to it, just the same.

In the case where I want to "extend" functionality in Foo application, I simply register a "dummy" module inside of Core (so that it's dependencies are met at compile time), and register a module in Foo that has the valid implementations within it's module.

:+1:

I have implemented dagger 2 in my library project and when i am using this library in my main project then i am facing cannot resolve symbol DaggerApplicationComponent issue.

I tried the above solution but i didn't know that how can i use another component in main project. So, can you please explain in brief. @cody1024d

@sahir

I have since moved on from that project (and company), but I will explain to the best of my memory. I don't have access to the source code, to post snippets, unfortunately, so bare with me! :)

Let's say I'm trying to build a Database-Access related object graph. In my library project, I would create a DatabaseComponent interface, and within it, specify ONLY the dependencies that the library project itself can satisfy all on it's own.

Within the library project, in order to actually compile the project, I ensure there are Stubbed-out modules that are able to provide the dependencies defined within the DatabaseComponent (I stub out the provide methods by either returning null, or by returning No-Oped objects).

Then, in my main project, I can create a MainProjectDatabaseComponent (or something named similarly), and have that interface extend from DatabaseComponent. Then, within the actual definition of MainProjectDatabaseComponent, I can define further dependencies that the Main Project has knowledge of, and can provide. In this example, it could be potential DAOs that are relevant to models in the main project.

Then, within the main project, I provide the REAL modules, that can satisfy all dependencies listed in the MainProjectDatabaseComponent. And, since MainProjectDatabaseComponent extends DatabaseComponent, these modules would have to satisfy those dependencies as well.

@cody1024d Thank you for detail explanation. It is working now.

There are a number of issues for this, I suggest looking through it if you still have questions on this

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pedrovarela86 picture pedrovarela86  路  3Comments

matpag picture matpag  路  3Comments

6bangs picture 6bangs  路  3Comments

SteinerOk picture SteinerOk  路  3Comments

pyricau picture pyricau  路  4Comments