5

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.

naser khsoravi
  • 473
  • 7
  • 16
  • Please read [here][https://stackoverflow.com/q/44912080/1837367] and update your question accordingly to include the necessary parts. This seems like a simple error, but you are not providing the necessary information – David Medenjak Aug 24 '17 at 12:12
  • @DavidMedenjak thanks that gave me better sight but still i can't figure what is my fault. My code is simple. I update my code please see my code. – naser khsoravi Aug 24 '17 at 14:56
  • Please also include the full error message – David Medenjak Aug 24 '17 at 15:08
  • @DavidMedenjak ` Error:(13, 8) error: java.lang.String cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method. java.lang.String is injected at naserkhosravi.dagger23.MainActivity.initFirstUserName(firstName) naserkhosravi.dagger23.MainActivity is injected at naserkhosravi.dagger23.component.MainActivityComponent.inject(mainActivity)` – naser khsoravi Aug 24 '17 at 15:23
  • You still did not include the necessary parts. You have a `initFirstUserName` method that can not be satisfied, neither did you include it. Please read the linked question thoroughly and make sure to understand, I'm voting to close this as a duplicate – David Medenjak Aug 24 '17 at 16:08
  • Possible duplicate of [How do I fix Dagger 2 error '... cannot be provided \[...\]'?](https://stackoverflow.com/questions/44912080/how-do-i-fix-dagger-2-error-cannot-be-provided) – David Medenjak Aug 24 '17 at 16:08
  • @DavidMedenjak I satisfy strings in UserModule and wire them in MainActivityComponent to MainActivity and initFirstUserName must be automatically call and satisfy . I didn't see any problem.can you give me a right example? – naser khsoravi Aug 24 '17 at 16:29

1 Answers1

3

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

David Rawson
  • 20,912
  • 7
  • 88
  • 124