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?
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.
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.
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.
Dagger doesn't support injection on private fields.
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:
B
, which consumes A
, is not under your control and not DI-aware, you will have no way to add the @Inject
annotation.@Provides
(or @Binds
in newer Dagger versions) to identify which implementation to use.@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.
null
sometimes that logic can live in a @Provides
method. Make sure you annotate the injection sites as @Nullable
.@Provides
method, particularly if the choice depends on runtime environment.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With