My issue with the Android-specific pattern is, if you use their AndroidInjection
class, there is no way to members inject other objects besides Activities
/Fragments
/custom views/adapters, except with the Application Component. This is because you cannot get a reference the the Subcomponent
(AndroidInjector
) used to inject Activities
/Fragments
.
This makes injecting Dialogs (if you use DialogFragments
).
The AndroidInjection
class seems to support just the core Android types.
What follows is not an answer to your question, but an explanation why you shouldn't be asking this question at all.
You should avoid injections into custom
Views
in general. The reasons for this are listed in this article.In addition, I advice to avoid the new injection method that involves
AndroidInjection
class. It is discussed in this video tutorial.First, you should think over Vasily's answer.
But let's think for a moment how we did this before Dagger Android? We built a subcomponent from the component that was taken from the
Application
class. Later, we could use this subcomponent in order to inject fields, for example, of a custom view.So, we'll try to do the exact same thing now.
Suppose, our aim is to inject
MyAdapter
class into aMyButton
:And let's make the adapter have a dependency on the activity
Context
, not applicationContext
:Let's start with the custom
Application
class.MyApplication.java
AppComponent.java:
AppModule.java
ActivityBindingModule.java
AndroidSupportInjectionModule.java
is shipping with dagger itself. If you do not use classes from support package (i.e.android.support.v4.app.Fragment
instead ofandroid.app.Fragment
), then useAndroidInjectionModule.java
.MySubcomponent.java
SubcomponentModule.java
MainActivity.java
Having all of these, now here's how
MyButton
will look like:I admit that this looks hacky and certainly not an approach to stick to. I'm happy to see a better approach.
The issue of whether the dagger-android classes like
AndroidInjector
should support injection inside Views or not has been discussed in the following Github issue:https://github.com/google/dagger/issues/720
Quoting from one of the library authors:
This reinforces the opinion expressed in Vasily's answer.
To add further, people often seem to want to inject model-layer dependencies inside their custom views. This is a bad idea as it goes against the software engineering principle of separation of concerns.
The correct solution for associating a view and a model is to write an adapter like the adapters for RecyclerView and ListView. You can inject the model-layer dependency at the Fragment or Presenter level and set the adapter there.
You can always just inject the component itself. Just add a field for the component to your Activity / Fragment and let Dagger inject it along with the rest.