EladB
EladB

Reputation: 326

Android: Dagger 2 and constructor injection

I'm new to dagger and my constructor/method injection doesn't seem to work. Doesn't work meaning the injected fields are still requested.

This is my code:

@Module
public class AppContextModule {

    private final Context appContext;

    public AppContextModule(Context appContext) {
        this.appContext = appContext;
    }

    @Singleton
    @Provides
    public Context getAppContext() {
        return appContext;
    }

}

@Singleton
@Component(modules = {AppContextModule.class})
public interface MyComponent {

    void inject(ActivitiesLifeCycleListener obj);

    void inject(WebViewManager obj);

    Context context();

}

public final class MyClass {

    private final WeakReference<Context> mAppContext;

    @Inject
    public MyClass(Context context)  {
        this.mAppContext = context
    }

}

public class MyActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        MyClass my = new MyClass(); // The IDE requests context!

    }

}

"MyClass" still requires "Context" although I used the "@Inject" annotation above the constructor. What am I missing?

Do I even need to expose my Context?

Thanks.

Upvotes: 5

Views: 4231

Answers (1)

David Medenjak
David Medenjak

Reputation: 34532

Well...you declare your constructor

public MyClass(Context context)  {
    this.mAppContext = context
}

And then call it without any parameters

MyClass my = new MyClass(); // The IDE requests context!

Why do you think this should work? This is plain java, no dagger involved, and you are trying to create some new object without supplying the arguments needed.


Dagger is no magic that changes how java works. To use constructor injection you have to actually use Dagger to inject your fields.

public class MyActivity extends BaseActivity {

    @Inject
    MyClass mMyClass; // mark field for injection

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // todo ... create component

        component.inject(this); // inject fields
    }

}

Given that you provide a Context somewhere (you'll get a Context must be provided... compile error if it is not) dagger will then inject your activity with MyClass by calling inject—no magic. The inject method will assign the object to your field.


Constructor injection only means that you don't have to use a module and include a method to provide the object. It does not just magically create objects out of thin air or change the way constructors work.

Upvotes: 10

Related Questions