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.
Note: The Dagger basics page covers how to use the Dagger @Inject annotation in constructors. This annotation tells Dagger how to create instances of a class. Instead of creating the dependencies an activity requires in the onCreate() method, you want Dagger to populate those dependencies for you.
With the @Inject annotation on the constructor, we instruct Dagger that an object of this class can be injected into other objects. Dagger automatically calls this constructor, if an instance of this class is requested.
Dagger is a compile-time framework for dependency injection. It uses no reflection or runtime bytecode generation, does all its analysis at compile-time, and generates plain Java source code.
It's officially deprecated and you can pretty much ignore it. Google's framework, which became dominant in Android ecosystem, was originally called Dagger 2. Sometimes we still refer to it as such, but, in most cases, we simply call it Dagger today.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With