Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qualified Method Injection In Dagger 2

I Successfully used Qualified field injection construct injection and method injection , i have expect from dagger 2.10 to inject dependency to Qualified method like following code:

public class MainActivity extends AppCompatActivity {

   @Override protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);
   DaggerMainActivityComponent.create().inject(this);
   }

  @Named("firstName")
  @Inject
  void initFirstName(String firstName){
  }

  @Named("lastName")
  @Inject
  void initLastName(String lastName){
  }

@Module public class UserModule {

   @Named("firstName")
   @Provides
   String provideFirstUserName() {
   return "Nasser";
   }

  @Named("lastName")
  @Provides
  String provideLastUserName() {
    return "Khosravi";
  }
 }

 @Component(modules = { UserModule.class})
 public interface MainActivityComponent {

  void inject(MainActivity mainActivity);

  @Named("firstName")
  String getFirstName();

 @Named("lastName")
 String getLastName();
 }
}

but when i use this code i get :
java.lang.String cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method.


There is a lot of simple tutorial about dagger in web but all of them are same and i can't find any example about Qualified method injection .

Why I Want Method Injection?

I prefer method injection over field injection because it is :

  • clear than field injection
  • you can simply set breack point and debug value injected
  • you can assign value injected to private field
  • ....

My Question:

Is it possible Qualified method injection in dagger 2? or my expect of method injection is wrong?
If it'a possible,How i can achieve it?

thanks for any advice.

like image 910
naser khsoravi Avatar asked Oct 18 '22 07:10

naser khsoravi


1 Answers

You are almost there, but you probably need to clear up a few things:

What is qualified by the @Named annotation? Dependencies (not methods) are qualified.

Who can receive qualified dependencies? Constructors, fields, or methods.

How can a method receive a qualified dependency?

The same way a constructor would receive a qualified dependency:

@Inject
void initFirstName(@Named("firstName") String firstName) {
    //
}

Notice that the method itself is not qualified but the parameters received by the method are qualified.

Why should we use method injection?

Your use case is probably not so suited for method injection. A good use case is where you want to execute a method immediately after a constructor is called (for instance setting a listener). You might do this to avoid the this reference from escaping in a constructor. See this question for an explanation.

you can simply set breack point and debug value injected

If you want to debug you can always set a breakpoint after the call to the inject() method of the Component and inspect the fields of the injection site using Alt-F8.

The best practice for Android is to use field injection inside Activity, Fragment and other OS-instantiated classes. Then use constructor injection for dependencies like repositories, data sources etc.

If you follow best practices for injection then your code will be easier for other programmers to follow and it will be easier for you to get help here on StackOverflow as well.

Related:

Method injection using Dagger 2

like image 162
David Rawson Avatar answered Oct 21 '22 01:10

David Rawson