Injecting fields without the c Dagger 2 constructor

On the site with documentation for Dagger 2, there is the following example code and words:

class CoffeeMaker {
  @Inject Heater heater;
  @Inject Pump pump;

  ...
}

If your class has @Inject-annotated fields but no @Inject-annotated constructor, Dagger will inject those fields if requested, but will not create new instances. Add a no-argument constructor with the @Inject annotation to indicate that Dagger may create instances as well.

What does this mean? I.e., if there is no constructor with @Inject, how will Dagger be inject these "if requested, but will not create new instances" fields?

I.e. as far as I understand, here:

class CoffeeMaker @Inject (Heater heater) {
}

If the Heater object has not been created before, dagger will create a new object (relatively speaking, heater = Heater()), but if its object is now used by another class, then we will get a reference to the same object that is used by another class (relatively speaking, heater = heaterObj). And what will happen here?

class CoffeeMaker {
   @Inject Heater heater;
}

In case the Heater object has not been created before? And if this is its object is it currently being used by another class?

Author: Ksenia, 2019-09-05

1 answers

In this case, you need to explicitly inject. Example of injecting fields in Fragment() on android:

class AlbumsFragment: Fragment() {

    @Inject
    lateinit var mAdapter: AlbumsListAdapter

    @Inject
    lateinit var factory: CustomViewModelFactory

    lateinit var viewModel: AlbumViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setHasOptionsMenu(false)

        (activity?.application as App).getComponent().inject(this)
        viewModel = ViewModelProviders.of(this, factory).get(AlbumViewModel::class.java)

        viewModel.setAdapter(mAdapter)

        mAdapter.setActivity(activity as AppCompatActivity)
    }
}

Component interface:

@Component(modules = [AppModule::class])
interface ApplicationComponent {

    fun inject(fragment: AlbumsFragment)

}

What does this mean? I.e., if there is no constructor with @Inject, how will Dagger inject these "if requested, but will not create new instances" fields?

The fields are initialized after the method:

(activity?.application as App).getComponent().inject(this)

That is, if this call is not made, the fields will not be initialized.

If the Heater object wasn't created before? And if such an object is now used by another class?

If the fields in Module() are not marked as singletons, then new objects will be created, and if they are marked, then one instance will be injected for all classes.

 1
Author: Vennic, 2019-09-05 16:44:17