Android Dagger Dependency Injection fails on private Fields
Asked Answered
A

4

20

I'm new to dagger (though I have experience with DI from working on Java EE WebApps using Weld).

What I'm trying to do is to inject a dependency into a class. The field is private.

Dagger then throws an exception stating it can't inject into a private field.

What's the reason for that?

After all it is possible to write to private fields using reflections, even on android..

If I set the visibility of the field to something other than private the injection seems to work.

Apotheosis answered 16/5, 2013 at 21:54 Comment(0)
A
23

Making a private field 'package visible' may not always be what you want. The Dagger documentation suggests the following:

Injecting final fields and private members. For best performance Dagger generates code. Work around this by using constructor injection.

Here's an example:

private ItemFactoryImpl itemFactory;
private BuildingFactory buildingFactory;

@Inject
public World(ItemFactoryImpl itemFactory, BuildingFactory buildingFactory) {
    this.itemFactory = itemFactory;
    this.buildingFactory = buildingFactory;
}
Ahmadahmar answered 27/4, 2014 at 11:46 Comment(2)
Nice, thanks for input. Constructor Injection is something I'm used to from working with CDI..Apotheosis
This works for constructable types, but Android OS types like Activity, Application, Fragment are not intended to be constructed by anything but the Android framework, so field injection is still needed in these cases. But this is good advice where you have control over the constructor.Sudan
S
41

Dagger cannot support private fields and still support code-generated adapters (to avoid reflection). The way systems like Guice support private fields is they change the access to the field reflectively before accessing them. Since dagger generates an InjectAdapter in the same package as the class to be injected, it can access package-friendly, protected, or public fields. It cannot access private fields.

One of Dagger's advantages IS that it avoids reflection, so using reflection to bypass field visibility is not a desirable feature.

Sudan answered 16/5, 2013 at 22:14 Comment(1)
Makes sense to me. Will mark this as correct answer. Thank You !Apotheosis
A
23

Making a private field 'package visible' may not always be what you want. The Dagger documentation suggests the following:

Injecting final fields and private members. For best performance Dagger generates code. Work around this by using constructor injection.

Here's an example:

private ItemFactoryImpl itemFactory;
private BuildingFactory buildingFactory;

@Inject
public World(ItemFactoryImpl itemFactory, BuildingFactory buildingFactory) {
    this.itemFactory = itemFactory;
    this.buildingFactory = buildingFactory;
}
Ahmadahmar answered 27/4, 2014 at 11:46 Comment(2)
Nice, thanks for input. Constructor Injection is something I'm used to from working with CDI..Apotheosis
This works for constructable types, but Android OS types like Activity, Application, Fragment are not intended to be constructed by anything but the Android framework, so field injection is still needed in these cases. But this is good advice where you have control over the constructor.Sudan
B
3

Just the remove the private to set the visibility of your field to package friendly.

Dagger doesn't support injection on private fields.

Baneful answered 16/5, 2013 at 22:0 Comment(0)
A
0

See Hilt Official documentation

Fields injected by Hilt cannot be private. Attempting to inject a private field with Hilt results in a compilation error.

  1. you can make the field public or
  2. use the constructor injection
Aleshia answered 1/9, 2022 at 12:9 Comment(2)
Please use block-quoting next time. Not doing so may result in future posts getting removed for plagiarism, and nobody wants that.Headstock
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Aemia

© 2022 - 2024 — McMap. All rights reserved.