Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Dagger 2: Inject versus Provides

I have a question regarding Android Dagger 2 und the usage of @Inject and @Provide annotations. Given are the following two simplified examples:

public class A {   String msg;    public A(String msg){     this.msg = msg;   } }  public class B {   public A a;    public B(A a){     this.a = a;   } }  @Module public class AModule {   @Provides   A providesA(){     return new A("blah");   }    @Provides   B ProvidesB(A a)   {     return new B(a);   } } 

The example is pretty straight forward, I have two methods in my AModule with @Provides annotations. Therefore, Dagger can create an object of B using an instance of A with the string blah.

My second example looks like this:

public class A {   String msg;    public A(String msg){     this.msg = msg;   } }  public class B {   public A a;    @Inject   public B(A a){     this.a = a;   } }  @Module public class AModule {   @Provides   A providesA(){     return new A("blah");   } } 

In this example, Dagger can create an instance of B because an object A can be created using AModule. The instance of B can be created because it's constructor uses the @Inject annotation.

So my question is: What's the difference between those two examples? Both seem to have the same semantics. Does the generated code differ and are there any pitfalls? Or is it just a matter or personal taste or best practices?

like image 987
Christian Ammann Avatar asked Aug 29 '16 13:08

Christian Ammann


People also ask

What is @inject in dagger?

Dagger 2 is a compile-time android dependency injection framework that uses Java Specification Request 330 and Annotations. Some of the basic annotations that are used in dagger 2 are: @Module This annotation is used over the class which is used to construct objects and provide the dependencies.

Which dependency injection is better in Android?

Hilt is Jetpack's recommended library for dependency injection in Android. Hilt defines a standard way to do DI in your application by providing containers for every Android class in your project and managing their lifecycles automatically for you.

What is dagger injection Android?

Dagger is arguably the most used Dependency Injection, or DI, framework for Android. Many Android projects use Dagger to simplify building and providing dependencies across the app. It gives you the ability to create specific scopes, modules, and components, where each forms a piece of a puzzle: The dependency graph.

Can a dagger inject a private field?

Dagger doesn't support injection on private fields.


1 Answers

They work similarly, and the @Inject style is preferred when you have such an easy choice like in your example. However, this isn't always the case:

  • If B, which consumes A, is not under your control and not DI-aware, you will have no way to add the @Inject annotation.
  • If B is an interface, you will need @Provides (or @Binds in newer Dagger versions) to identify which implementation to use.
  • If you choose not to use your Dagger object graph for every injected parameter, you can call the constructor manually whether it is marked @Inject or not. This might be the case if you want a specific instance or constant as a constructor parameter, but you can't or don't want to set up the binding for the whole object graph.

@Provides allows you to effectively create a factory method, with everything that allows. This is a great way to change which instances are included in your graph, or to effectively add to the class's constructor graph-wide if you can't (or shouldn't) change the class itself.

  • You can return an existing instance rather than a new one. Note that custom scopes (implemented in Dagger through subcomponents) might be a better fit for common cases, but if you have more complex instance control or use a third-party library that controls instances, you could put that into your factory method.
  • If you want your binding to return null sometimes that logic can live in a @Provides method. Make sure you annotate the injection sites as @Nullable.
  • You can choose between implementations with a factory method like a @Provides method, particularly if the choice depends on runtime environment.
  • You can run post-construction logic, including instance registration or initialization.
like image 111
Jeff Bowman Avatar answered Oct 09 '22 15:10

Jeff Bowman