Found the code and want to figure out how the Dagger2 works

So I blinded such a simple example and can not figure out how to connect it so that it worked

Have MainActivity

 public class MainActivity extends AppCompatActivity { @Inject protected ApiInterface apiInterface; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (apiInterface == null){ Log.e("TAG", "apiInterface == null"); }else { Log.e("TAG", "apiInterface != null : " + apiInterface.value); } } } 

I want to inject the apiInterface reference into the variable apiInterface . For this, I specify the @Inject keyword.

Now, so that Dagger knew what to inject there, I made a class like this

 @Module class ModelModule { @Provides @Singleton ApiInterface provideApiInterface() { return ApiModule.getApiInterface(); } } 

Now I understand Dagger when he sees the word @Inject and the type of the variable (as far as I understand it), he will look for someone who returns this type and find the ModelModule class in which the method provideApiInterface() returns what apiInterface needs.

This is the way to clarify this class.

 class ApiInterface { int value; ApiInterface() { this.value = 4; } } 

But now, in order to make it work, you need to specify @Component , which indicates from where to take the objects and where to implement ...

But this is a theory, since I don’t understand why it is needed ... We already indicated from where to take objects, and the word @Inject we indicate where to implement ... Why else do we need something?

Here is the problem, explain why you need @Component and how to compose it for a specific example, so that everything MainActivity and I could get the number 4 in MainActivity ...

EDIT So I blinded this component here

 @Singleton @Component(modules = {ModelModule.class}) interface AppComponent { void inject(ApiInterface apiInterface); } 

In MainActivity I still get null

Where is the mistake?

  • one
    because modules can be different and implementations can also be different. You ask a question about the goals pursued by the developers of the library, there are none. Perhaps you will help the article to get an idea. habrahabr.ru/post/279125 and habrahabr.ru/post/279641 - andreich
  • @andreich I added a question to the question - Aleksey Timoshchenko

2 answers 2

You need to create an AppComponent in MainActivity

 appComponent = DaggerAppComponent.builder().modelModule(new ModelModule()).build(); 

and make appComponent.inject(this)

  • I cannot specify inject(this) in the MainActivity as this method accepts ApiInterface apiInterface as I indicated in the edit ... - Aleksey Timoshchenko
  • I figured it out) - Aleksey Timoshchenko

That's right, without a component, nowhere, because without it your class, which sews up the dependencies, does not understand where they come from. If you pass a reference to yourself to the component (for example, through the inject () method), the component looks at your class, recognizes all the fields that need to be injected, and sends the request to the correct Module, reminding you that there may be several modules that can have the same return values , and the component indicates exactly the one you need in this situation.

As the commentator wrote above in your class, you need to create a component and pass a reference to your class to the component method. Required code just written above