Java – Use Dagger to inject the field

Use Dagger to inject the field… here is a solution to the problem.

Use Dagger to inject the field

I’m trying to inject my android context from one module to another. So far, here’s my code:

UserProfileModule.java

@Module(
        library = true
)
public class UserProfileModule {

@Inject Context _context;

@Provides
    public AccountUtils.UserProfile provideUserProfile() {
        return AccountUtils.getUserProfile(_context);
    }
}

The root module .java

@Module(
        injects = {
                PizzaApplication.class,
                UserProfileModule.class,
                MainActivity.class
        },
        includes = {
                UserProfileModule.class
        },
        library = true
)

public class RootModule {
    private final Context _context;

public RootModule(Context context) {
        _context = context;
    }

@Provides
    @Singleton
    public Context provideApplicationContext() {
        return _context;
    }
}

Whenever it tries to get the user profile, it fails and prompts that the object is empty. ]

Edit:

PizzaApplication.java

public class PizzaApplication extends Application {
    private ObjectGraph objectGraph;

@Override
    public void onCreate() {
        super.onCreate();
        injectDependencies();
    }

private void injectDependencies() {
        objectGraph = ObjectGraph.create(new RootModule(this));
        objectGraph.inject(this);
    }

public void inject(Object object) {
        objectGraph.inject(object);
    }
}

The main activity .java

public class MainActivity extends BaseActivity {

@InjectView(R.id.toolbar) public Toolbar _toolbar;
    @InjectView(R.id.drawer) public DrawerFrameLayout _drawer;
    @Inject public AccountUtils.UserProfile _profile;
    @Inject public Context _context;

 private NavigationDrawerFragment navigationDrawerFragment;

@Override
    protected void onCreate(Bundle saveInstanceState) {

Solution

tl; dr (short version):

  1. For a minimal working example of code, see my code on GitHub
  2. You don’t/shouldn’t inject Context from one module to another.
  3. The

  4. order/direction of module inclusions is reversed, and UserProfileModule should contain RootModule.

More details and comments about your code:

  1. You don’t need to inject anything into the module, the module only provides dependencies. In your case, simply use the module includes to provide the functionality you want.
  2. Remove library = true from the UserProfileModule because you only need it if the class specified in the inject list does not use the module's provider directly.
  3. As Niek Haarman says, you need to pass the RootModule and UserProfileModule instances to ObjectGraph.create in PizzaApplication’s onCreate.
  4. You are executing inject(this) in PizzaApplication, but it has no dependencies, so inject is not needed. Based on the sample code you provided, this makes me feel like you’re assuming that injecting at the application level will also inject activity dependencies…? You also need to inject your activity.
  5. If you inject in the onCreate of the activity, it will not be displayed – this is most likely missing.
  6. You are injecting a Context into an activity, but this is not required because you can use getApplicationContext() in an activity.

Here is the working code:

Root module:

@Module(
    injects = {MainActivity.class},
    library = true,
    complete = false
)
public class RootModule {
  private final Context _context;

public RootModule(Context context) {
    _context = context;
  }

@Provides
  @Singleton
  public Context provideApplicationContext() {
    return _context;
  }
}

User Profile Module:

@Module(includes = {RootModule.class})
public class UserProfileModule {
  @Provides
  public AccountUtils.UserProfile provideUserProfile(Context context) {
    return AccountUtils.getUserProfile(context);
  }
}

Main Activity:

public class MainActivity extends BaseActivity {

@Inject
  public AccountUtils.UserProfile _profile;

@Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ((PizzaApplication) getApplication()).inject(this);
    _profile.message();
  }

Pizza app:

public class PizzaApplication extends Application {
  private ObjectGraph objectGraph;

@Override
  public void onCreate() {
    super.onCreate();
    objectGraph = ObjectGraph.create(new RootModule(this), new UserProfileModule());
  }

public void inject(Object object) {
    objectGraph.inject(object);
  }
}

Related Problems and Solutions