question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Injecting Dependencies From Base Class

See original GitHub issue

In Dagger 1, you could call inject from a base class and have all dependencies satisfied for subclasses:

class BaseActivity extends Activity {
  @Inject Foo foo;

  public void onCreate(Bundle savedInstanceState) {
    objectGraph().inject(this);
  }
}

class MainActivity extends BaseActivity {
  @Inject Bar bar;

  @Override void onCreate(Bundle savedInstanceState) {
    super.onCreate();
    // both foo and bar will be available here
  }
}

This has changes in Dagger 2; injecting from a base class will only satisfy the base class’s dependencies, not it’s subclasses’s.

class BaseActivity extends Activity {
  @Inject Foo foo;

  public void onCreate(Bundle savedInstanceState) {
    component().inject(this);
  }
}

class MainActivity extends BaseActivity {
  @Inject Bar bar;

  @Override void onCreate(Bundle savedInstanceState) {
    super.onCreate();
    // only foo is available here, not bar
  }
}

Is there a recommended pattern for injecting dependencies from a base class, rather than calling inject in each of the subclasses?

Issue Analytics

  • State:closed
  • Created 9 years ago
  • Comments:22

github_iconTop GitHub Comments

3reactions
gk5885commented, Nov 17, 2014

Here’s how members injection methods work:

  1. You can make a members injection method for any type that has @Inject anywhere in its class hierarchy. If it doesn’t, you’ll get an error.
  2. All @Injected members in the entire type hierarchy will be injected: the argument type and all supertypes
  3. No members will be @Injected for subtypes of the argument type.

So, given the following:

final class Dep {
  @Inject Dep() {}
}

class A {
  @Inject Dep a;
}

class B extends A {
  @Inject Dep b;
}

class C extends B {
  @Inject Dep c;
}

@Component
interface TestComponent {
  B injectB(B instance);
}

The following test will pass:

TestComponent component = Dagger_TestComponent.create();
C instance = component.injectB(new C());
assertThat(instance.a).isNotNull();
assertThat(instance.b).isNotNull();
assertThat(instance.c).isNull();
0reactions
mcfongtwcommented, Oct 16, 2019

Tried the example posted by @JakeWharton, and member in SubClass was not injected. However, as I explore more in the generated code, that could possibly be done via the following:

abstract class BaseThing {
    @Inject
    String foo;

    public BaseThing() {
        this(DaggerBaseComponent.create());
    }

    public BaseThing(BaseComponent component) {
        component.inject(this);
    }
}
class RealThing extends BaseThing {
    @Inject CharSequence bar;

    public RealThing() {
        this(DaggerBaseComponent.create());
    }

    public RealThing(BaseComponent component) {
        component.inject(this);
    }
}

@Module
class BaseModule {
    @Provides
    String provideString() { return "String!"; }
    @Provides CharSequence provideCharSequence() { return "CharSeq!"; }
}

@Component(modules = BaseModule.class)
interface BaseComponent {
    void inject(BaseThing baseThing);
    void inject(RealThing realThing);
}

public class BaseExample {
    public static void main(String... args) {
        RealThing realThing = new RealThing();

        System.out.println("String? => " + realThing.foo);
        System.out.println("CharSeq? => " + realThing.bar);
    }
}

This way, bar is injected properly.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Handling Dependency Injection in Inherited Classes
In this post I have described a simple method for managing dependency injection in inherited classes, by creating a dependency aggregate class ......
Read more >
Implicitly injecting dependency in Base class while derived ...
I thought that Dependency dep should get injected automatically(through Constructor Injection) when derived class is resolved. But this doesnt seem to work when ......
Read more >
3 Exciting Methods for Dependency Injection With Inheritance ...
Dependency injection is a way to inject dependencies into a class for use in its methods. With dependency injection, the class becomes loosely...
Read more >
Dependency injection - .NET | Microsoft Learn
.NET supports the dependency injection (DI) software design pattern, which is a technique for achieving Inversion of Control (IoC) between ...
Read more >
Dependency Injection and Class Inheritance - Peter's Pattern
Dependency Injection and Class Inheritance. Once upon a project there was a base class: class abstract CommonLogic { protected ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found