Hilt videos popping one after the other like a tv series. I've been playing with hilt since it came but these videos have really solidified by understanding. ❤️❤️❤️❤️❤️❤️
Great video!! I don't know about performance but I think @Binds is meant for interface implementations and @Provides is meant for 3rd party libraries instances.
Hey @CodingWithMitch how time flies, alot have actually changed, ApplicationComponent has been deprecated, even though this is still well explained, you're such a great teacher. Thank you
The @Binds annotation tells Hilt which implementation to use when it needs to provide an instance of an interface. and @Provides is used when you need to provide some instances as in builder pattern for example Gson library you mentioned - not interface and library that you don't own it
*Edit 2:* My argument below is not _completely_ incorrect. See @Coding In Flow's response in this comment thread, which made me realize that @Bind's syntax is _exactly the same_ as @Provides' syntax with the provided value being an injected parameter instead of being manually constructed. So that can also be used as an argument for @Binds being simpler since it omits the method body. My original comment below. ---- @Binds _automatically_ injects all the constructor parameters of the implementation. It seemed simple in this case only because SomeInterfaceImpl had no parameters. Add 5 constructor parameters to inject into it and notice how @Binds requires no changes whatsoever. In contrast you have to enumerate the parameters twice for @Provides and update it every time you change SomeInterfaceImpl's constructor parameters. Thus, @Binds is the simpler one (albeit with an unfamiliar way of specifying the map from interface to implementation), whereas @Provides is more flexible, allowing arbitrary computation and construction during injection. *Edit:* Also, given the very pertinent RUclips link provided below by @Coding In Flow, I don't see why they couldn't have used a more succinct notation like: ``` @InstallIn(ActivityComponent::class) @Module @Binds([ map(from=SomeInterface, to=SomeInterfaceImpl), map(from=FooInterface, to=FooInterfaceImpl), // etc ]) abstract class MyModule() {} ```
Hi @moinneatier so quick question. For interfaces or classes you don't own, that may require multiple parameters, eg. EncryptedSharedPrefs, how would you declare those with @Binds (should you declare those with @Binds? no i guess?) I seem to be seeing having two Module.kt classes (one being abstract, the other for the classes you do own) as the best option, so you can still have @Binds doing the hidden constructor stuff and @Provides being more specific and requiring a method body. Any downsides to this approach?
@@nathanyattipoe2078 @Binds can only provide implementations whose constructor is marked @Inject, whether or not you own them -- Dagger/Hilt knows how to construct them. On the other hand, if the constructor doesn't have @Inject (e.g. it takes non-injectable arguments like a master key or file path which Dagger/Hilt wouldn't know how to inject anyway), then injecting it requires using @Provides. So if you wanted to inject EncryptedSharedPrefs, it would need to be @Provides-ed.
Binding is not new in Hilt. It has been used in Dagger for quite a while. Additionally to what has already been said, we also cannot @Provide framework classes. In MVP (and other patterns for that matter) we can use the typed activity reference from the activity scope and bind it to our view interface (implemented by that activity). There's more. There are even performance benefits as specified in the docs: "Note: Using @Binds is the preferred way to define an alias because Dagger only needs the module at compile time, and can avoid class loading the module at runtime."
You don't have to construct the object inside the @Provides method's body. You can declare it as a method parameter just like in the @Binds method. The benefit of binds are simply: no method body and more efficient generated code
Congratulations Mitch! I was afraid to jump in Dagger World, I knew the learning curve was steep and long. Thanks Jesus for Hilt and for you! Now DI is very much understandable! It's something new which adds up to me that I did not have to pass through Dagger to reach the Hilt. I have one question: How can I inject a Class into a ViewHolder using Hilt? Is there a way instead of double inject constructing?
This was a very well done video and the best I have watched concerning Hilt and dependency Injection. Thank you Mitch for sharing your knowledge about Hilt.
Honestly after diving into all this and understanding it fully, this whole Dependency Injection stuff seems like a massive, hairy, goofy hack for a problem that should be solved at the language level and not duct-taped together with very odd syntax, annotations and hard to understand code generation and use cases that requires deep understand of things that really should be abstracted away Feels like it's time for a revamp of how android apps are built from the ground up
Hi Mitch, first thank you for this useful content. I think it's simply described in the Hile docs links title: @Binds for interface imp but @Provides for third party libraries instance or even our custom code as you mentioned "@Provides works for all" Thanks,
Thank you so much Mitch, I'm in a OpenClassrooms Android dev training and without your free courses (and some others too) things should be much more complicated.
Bro Mitch, Come on, For @Bind it's working completely fine and accordingly. During using of Gson with @Bind, you were getting compile time error. The reason behind this is, Gson not an interface it's a class, and also it's coming from third party library, so you can't inject constructor for that. Not a interface and unable inject constructor, for these two reason you were getting this error. For @Bind: you should pass implementation class of a interface as a parameter and you need to return interface that implemented. For @Provide : You can use this annotation whenever there is no scope to inject constructor, like third party library classes. Here Gson, we can't modify this class, for that reason we can use @Provide by initialize the Gson object. Mitch, If I explained anything wrong please let me know.
An amazing series, quite frankly Hilt is much simpler and easy to understand, i have been thinkering with Dagger Android recently and all that boilerplate and building the component is just a pain in the ass, and then there was Hilt (say no more). Amazing videos btw (y)
Great video. HILT is definitely an improvement over Dagger. Still Koin is my first choice, at least for the personal projects. Thanks again for the great HILT series.
Nice video. I was searching some days back abt how to inject an interface instance to help me during unit testing n got the answer today in this video.
why wouldn't you just say that @Binds simply bind the Provided implementation of an Interface to it's interface type. and the @Provides is used to Provide an instance of anything.
Exactly! It's kinda intuitive. @Binds binds two things. In case of interfaces, using provides like he did would mean that you would've to create the instances your self, but if you use binds, then hilt will just use constructor injection to provide the instance.
@@syedtayyabulmazhar6945 Well put, it also adds a lot of code and starts to get nasty looking if you are trying to provide an interface that has properties that also require dependencies... @Binds does it all for you in a few lines.
Actually, you can do it with "complex" abstract bind as well, but you will need to use @provide inside companion object @InstallIn(ActivityComponent::class) @Module abstract class ComplexModule { companion object { @ActivityScoped @Provides fun providesString(): String = "Some thing" @ActivityScoped @Provides fun bindGson(): Gson = Gson() } @ActivityScoped @Binds abstract fun bindSomeInterface(someInterfaceImp: SomeInterfaceImp): SomeInterface }
QUESTION: I believe what you showed to achieve in the video was to call "getAThing()" method get a string from it. Calling this method prints a string in the MainAct->onCreate() method. I did not understand what was the need of binding "SomeInterfaceImpl" class to "SomeInterface" interface ? If I set "SomeInterfaceImpl" instead of "SomeInterface" in the "SomeClass" constructor. I can call the method like class SomeClass @Inject constructor( private val someInterfaceImpl: SomeInterfaceImpl ) "someInterfaceImpl.getAThing() " directly. Note: I am new to HILT and DAGGER never used it before 😑
Nice video! the provideSomeString part in the Module is a little confusing tho, dont fully understand how the constructor value is connected to the Module
Wow, I thought that only I had difficulties to understand the documentation, when I don't understand the documentation I get frustrated and wonder where to find better examples? stackOverflow rs rs rs. Thanks again and more success for your channel.
The reason @Binds did not work in that example was that Dagger could not instantiate the Gson instance since its a third party library, the parameter in the abstract function for binds must have a Injectable constructor
Notice how you had to explicitly create the instance of SomeInterfaceImpl when using @Provides, even though you had annotated it's constructor with @Inject? This means that when you don't have access to the code(as in case of Gson) you can use @Provides to provide it's instance(like you did with Gson). In case of SomeInterface you already had it's implemention SomeInterfaceImpl with a constructor annotated with @Inject, so you should use @Binds in this case because then you won't have to explicitly instantiate SomeInterfaceImpl, rather you can just bind SomeInterface to the constructor of SomeInterfaceImpl. TL:DR: @Binds is for binding one class to another. @Provides is for explicitly providing an instance of class. Hope i made some sense :D.
Hi Mitch, Thank you very much for such a nice video. I just want to know what if I want to have two implementations of an interface and want to use these two in different classes?
Great video. I have a question. As you said, @Module abstract class SomeModule {@Binds.... is more complex then @Module class SomeModule { @Provides. My question is, "Is there some case that --@Mudle class SomeMudule { @Provides...-- can't do DI?"
Just to confirm. Dagger-Hilt can create instances of a class who has a constructor who is either parameter-less or parameter with static value. Please help me on this.
hey mitch i have a question, how to provides a activity context into another class that required it ? I need to pass a context to a shared preference class
You don't understand `@Binds`. It's just "bind implementation of parameter type to return type". Only reason why it knows how to construct parameter type is because it has `@Inject` constructor.
You are providing misleading information. You complain that the binds annotation does not always work but: At minute 2:52 you can clearly see how it says "inject interfaces with @bind" ( The @Binds annotation tells Hilt which implementation to use when it needs to provide an instance of an interface) Then at minute 10:18 you try to implement an actual class and complaint it doesn't work. 2) Even of by some crazy reason you did not realize about point one. You start by saying you need to tell hilt how to build this instance yet on the bind gson example you request by parameter an instance of the same class you already know hilt doesn't know how to build. What where you expecting? Difference between bind and provide its quite clear if you read the docs
@Binds generates more efficient code than @Provides because it never creates an implementation for that module. The method is also more concise
Source?
@@codingwithmitch ruclips.net/video/-UWWFBEhW3Q/видео.html and you should see it in the generated code
@@codinginflow Ok so binds is "more efficient" (how much? who actually knows)
@@codingwithmitch In Java the Binds method was easier to read and parse than Provides, maybe in Kotlin's syntax it's not the case anymore
@@codinginflow I would say that yes
Hilt videos popping one after the other like a tv series. I've been playing with hilt since it came but these videos have really solidified by understanding. ❤️❤️❤️❤️❤️❤️
Great video!!
I don't know about performance but I think @Binds is meant for interface implementations and @Provides is meant for 3rd party libraries instances.
Decided to learn DI over the holiday break. This video series on hilt is much easier to understand than the codelab provided by Google. Appreciate it!
Hey @CodingWithMitch how time flies, alot have actually changed, ApplicationComponent has been deprecated, even though this is still well explained, you're such a great teacher. Thank you
@Binds as the name says is for binding classes (which are already provided) to interfaces. @Provides however provides classes by "creating" them
The @Binds annotation tells Hilt which implementation to use when it needs to provide an instance of an interface.
and @Provides is used when you need to provide some instances as in builder pattern for example Gson library you mentioned - not interface and library that you don't own it
*Edit 2:* My argument below is not _completely_ incorrect. See @Coding In Flow's response in this comment thread, which made me realize that @Bind's syntax is _exactly the same_ as @Provides' syntax with the provided value being an injected parameter instead of being manually constructed. So that can also be used as an argument for @Binds being simpler since it omits the method body. My original comment below.
----
@Binds _automatically_ injects all the constructor parameters of the implementation. It seemed simple in this case only because SomeInterfaceImpl had no parameters. Add 5 constructor parameters to inject into it and notice how @Binds requires no changes whatsoever. In contrast you have to enumerate the parameters twice for @Provides and update it every time you change SomeInterfaceImpl's constructor parameters. Thus, @Binds is the simpler one (albeit with an unfamiliar way of specifying the map from interface to implementation), whereas @Provides is more flexible, allowing arbitrary computation and construction during injection.
*Edit:* Also, given the very pertinent RUclips link provided below by @Coding In Flow, I don't see why they couldn't have used a more succinct notation like:
```
@InstallIn(ActivityComponent::class)
@Module
@Binds([
map(from=SomeInterface, to=SomeInterfaceImpl),
map(from=FooInterface, to=FooInterfaceImpl),
// etc
])
abstract class MyModule() {}
```
Hi @moinneatier so quick question. For interfaces or classes you don't own, that may require multiple parameters, eg. EncryptedSharedPrefs, how would you declare those with @Binds (should you declare those with @Binds? no i guess?) I seem to be seeing having two Module.kt classes (one being abstract, the other for the classes you do own) as the best option, so you can still have @Binds doing the hidden constructor stuff and @Provides being more specific and requiring a method body. Any downsides to this approach?
@@nathanyattipoe2078 @Binds can only provide implementations whose constructor is marked @Inject, whether or not you own them -- Dagger/Hilt knows how to construct them. On the other hand, if the constructor doesn't have @Inject (e.g. it takes non-injectable arguments like a master key or file path which Dagger/Hilt wouldn't know how to inject anyway), then injecting it requires using @Provides. So if you wanted to inject EncryptedSharedPrefs, it would need to be @Provides-ed.
Binding is not new in Hilt. It has been used in Dagger for quite a while. Additionally to what has already been said, we also cannot @Provide framework classes. In MVP (and other patterns for that matter) we can use the typed activity reference from the activity scope and bind it to our view interface (implemented by that activity).
There's more. There are even performance benefits as specified in the docs: "Note: Using @Binds is the preferred way to define an alias because Dagger only needs the module at compile time, and can avoid class loading the module at runtime."
You don't have to construct the object inside the @Provides method's body. You can declare it as a method parameter just like in the @Binds method. The benefit of binds are simply: no method body and more efficient generated code
@@codinginflow Ah, that's an excellent point! Edited my original comment to correct myself, thanks!
I think this series HILT Express 🙌❤❤❤❤👌
This series was a godsend for me thanks for the hard work! I think a follow up “using hilt with jetpack compose” video would be great as well.
Congratulations Mitch! I was afraid to jump in Dagger World, I knew the learning curve was steep and long. Thanks Jesus for Hilt and for you! Now DI is very much understandable!
It's something new which adds up to me that I did not have to pass through Dagger to reach the Hilt. I have one question: How can I inject a Class into a ViewHolder using Hilt? Is there a way instead of double inject constructing?
android hilt documentation was a little bit confusing at the @Bind and @Provides part, thank you for explaining it better.
Thanks for hilt❤. Excited for the coming clean architecture sample.
Check out the master if you want now github.com/mitchtabian/Dagger-Hilt-Playerground
@@codingwithmitch thanks👍I'll checkout.
Thank you. I also was going through the documentation and was asking the same questions. I had an inkling that I should just do @Provides.
This was a very well done video and the best I have watched concerning Hilt and dependency Injection. Thank you Mitch for sharing your knowledge about Hilt.
Can you also do a tutorial on Android Notifications and Alarm Manager?
Thanks appreciate it
@@chuka_obi5167 Notifications will be in a few months
Thank you for great video. Thank you for helping the Android community.
7:00 Use @InstallIn(SingletonComponent::class) instead of @InstallIn(ApplicationComponent::class)
Honestly after diving into all this and understanding it fully, this whole Dependency Injection stuff seems like a massive, hairy, goofy hack for a problem that should be solved at the language level and not duct-taped together with very odd syntax, annotations and hard to understand code generation and use cases that requires deep understand of things that really should be abstracted away
Feels like it's time for a revamp of how android apps are built from the ground up
Hi Mitch, first thank you for this useful content.
I think it's simply described in the Hile docs links title: @Binds for interface imp but @Provides for third party libraries instance or even our custom code as you mentioned "@Provides works for all"
Thanks,
Thank you so much Mitch, I'm in a OpenClassrooms Android dev training and without your free courses (and some others too) things should be much more complicated.
best series on hilt so far
Bro Mitch,
Come on,
For @Bind it's working completely fine and accordingly.
During using of Gson with @Bind, you were getting compile time error. The reason behind this is, Gson not an interface it's a class, and also it's coming from third party library, so you can't inject constructor for that. Not a interface and unable inject constructor, for these two reason you were getting this error.
For @Bind: you should pass implementation class of a interface as a parameter and you need to return interface that implemented.
For @Provide : You can use this annotation whenever there is no scope to inject constructor, like third party library classes. Here Gson, we can't modify this class, for that reason we can use @Provide by initialize the Gson object.
Mitch, If I explained anything wrong please let me know.
An amazing series, quite frankly Hilt is much simpler and easy to understand, i have been thinkering with Dagger Android recently and all that boilerplate and building the component is just a pain in the ass, and then there was Hilt (say no more). Amazing videos btw (y)
I'm so proud of myself I noticed that error at 8:17 ever before Mitch mentioned it, and it's my first day with Hilt ( and with Dagger in general) 😀
Thanks for this tutorial, is great!, Do we need a lot of class modules depending on the scope?
Great video. HILT is definitely an improvement over Dagger. Still Koin is my first choice, at least for the personal projects. Thanks again for the great HILT series.
Hey Mitch thanks in general for pointing out with this series the importance of using Dependency Injection.
Superb series ♥
Nice video. I was searching some days back abt how to inject an interface instance to help me during unit testing n got the answer today in this video.
What about module declaration with class vs object. I saw those two in use but don't know if there is any meaningful difference?
Really nice job Mitch! I have really enjoyed this series. I've finally understood Hilt and DI much better!
Dagger gave me a headache, but this hilt is pretty awesome!
I think there should be a meetup group calls keepUpWithMitch
why wouldn't you just say that @Binds simply bind the Provided implementation of an Interface to it's interface type.
and the @Provides is used to Provide an instance of anything.
Exactly! It's kinda intuitive. @Binds binds two things. In case of interfaces, using provides like he did would mean that you would've to create the instances your self, but if you use binds, then hilt will just use constructor injection to provide the instance.
@@syedtayyabulmazhar6945 Well put, it also adds a lot of code and starts to get nasty looking if you are trying to provide an interface that has properties that also require dependencies... @Binds does it all for you in a few lines.
i like his voice i always play his video before i go to bed
Are you playing Age of Empires in the back?
No but that was a sick game. Age of empires 2 was my jam
two celebrity coder people talking about nerdy games
@@prashantsurti5788 xD
@@codingwithmitch AOE 3 its mine xD
çok iyi ya :)
NOTE:: ApplicationComponent is renamed to SingletonComponent
Actually, you can do it with "complex" abstract bind as well, but you will need to use @provide inside companion object
@InstallIn(ActivityComponent::class)
@Module
abstract class ComplexModule {
companion object {
@ActivityScoped
@Provides
fun providesString(): String = "Some thing"
@ActivityScoped
@Provides
fun bindGson(): Gson = Gson()
}
@ActivityScoped
@Binds
abstract fun bindSomeInterface(someInterfaceImp: SomeInterfaceImp): SomeInterface
}
hi, could you explain why use companion object in abstract class for @Module?. As i know companion object is similar static in java, right?
Thanks a lot Mitch! Here's your engagement
thanks, is this still most efficient, or is there any updates?
awesome series .. thank you mitch
that is pretty much cool , thanks Mitch for your effort
Hi Mitch . If we providing dependency from module ..do we still need to keep @Inject constructor for the same class?
QUESTION:
I believe what you showed to achieve in the video was to call "getAThing()" method get a string from it.
Calling this method prints a string in the MainAct->onCreate() method.
I did not understand what was the need of binding "SomeInterfaceImpl" class to "SomeInterface" interface ?
If I set "SomeInterfaceImpl" instead of "SomeInterface" in the "SomeClass" constructor.
I can call the method like
class SomeClass
@Inject
constructor(
private val someInterfaceImpl: SomeInterfaceImpl
)
"someInterfaceImpl.getAThing() " directly.
Note: I am new to HILT and DAGGER never used it before 😑
Hello dear teacher and friends,
thanks for your awesome course
How can I provide third party libraries with binds annotation?
Nice video! the provideSomeString part in the Module is a little confusing tho, dont fully understand how the constructor value is connected to the Module
Can you also talk about the limitations of hilt on your next video perhaps ?
Wow, I thought that only I had difficulties to understand the documentation, when I don't understand the documentation I get frustrated and wonder where to find better examples? stackOverflow rs rs rs. Thanks again and more success for your channel.
Mitch, again the fist in the queue waiting for your next video. Thanks. Please try. to create the next video focused on UnitTesting for Hilt DI.
The reason @Binds did not work in that example was that Dagger could not instantiate the Gson instance since its a third party library, the parameter in the abstract function for binds must have a Injectable constructor
Notice how you had to explicitly create the instance of SomeInterfaceImpl when using @Provides, even though you had annotated it's constructor with @Inject? This means that when you don't have access to the code(as in case of Gson) you can use @Provides to provide it's instance(like you did with Gson).
In case of SomeInterface you already had it's implemention SomeInterfaceImpl with a constructor annotated with @Inject, so you should use @Binds in this case because then you won't have to explicitly instantiate SomeInterfaceImpl, rather you can just bind SomeInterface to the constructor of SomeInterfaceImpl.
TL:DR: @Binds is for binding one class to another. @Provides is for explicitly providing an instance of class.
Hope i made some sense :D.
Really enjoying this series... Thanks a ton!!
Thanks for your explanation. I am waiting other videos tutorial. Thank sir. God Bless You
How do I use it with a viewmodel?
Hi Mitch, Thank you very much for such a nice video. I just want to know what if I want to have two implementations of an interface and want to use these two in different classes?
One question. My @binds function is showing as "never used" but functions correctly. Is it normal?
Great video. I have a question.
As you said,
@Module abstract class SomeModule {@Binds....
is more complex then
@Module class SomeModule { @Provides.
My question is,
"Is there some case that --@Mudle class SomeMudule { @Provides...-- can't do DI?"
Opps.. I'm sorry you already answered my question at end of this video^^;... ("I don't have the scenario")
Really helpful playlist
What if we always use ApplicationComponent or SingletonComponent and @Singleton? Great videos you have a new subscriber!
It just means everything will exist as long as the application is alive
Your training is excellent
Thanks, Very simple and very helpful.
In Hilt, if I have to pass a parameter at runtime to a module, how can I do it? I could need to pass a parameter to a @Provides method, how do it?
Components and builders please like a component that depends on modules and has a builder for some one off value
great vid Mitch, even greater shirt. 9000/10
Just to confirm. Dagger-Hilt can create instances of a class who has a constructor who is either parameter-less or parameter with static value. Please help me on this.
hey mitch i have a question, how to provides a activity context into another class that required it ? I need to pass a context to a shared preference class
I love your videos. Thank you
thanks great video again!
Good work keep it up waiting for next videos 👍
Really helpful. Thanks.
6:31 ApplicationComponent is deprecated, use SingletonComponent
Thanks Mitch, good work :)
Thanks a lot. Very nice explanation Thank you Thank you for making its much simpler.
Thanks for your videos they are very helpful
Huge help 🙌🏻
Why did you return the impl class and not the interface itself in Module class?
Because I want to use the implementation. You can't instantiate an interface.
Hey is that Vegeta on you t-shirt?
yep
Using @Provides and if I try to inject it in different activities and fragment doesn't work!
Man Mitch is fire
tnx :x best teacher
best teacher
@CodingWIthMItch Are you Armenian?
Canadian. I don't know my genetic heritage though. Ask me again in a month. I just sent in the "23 and me" genetic testing thingy
@@codingwithmitch Seriously? maybe Armenians made you sick of answering such a questions. lol
You don't understand `@Binds`. It's just "bind implementation of parameter type to return type". Only reason why it knows how to construct parameter type is because it has `@Inject` constructor.
just Start from timestamp 10:46
Thanks Sir
😍🔥
keeep up the good work :)
damn I literally came here only because I didn't get it from the docs ahaha
Awesome Boss
gacho! gacho!
as per doucemation in daggerhilt, easy way is a bad practice. please check again
More more moreeeeeeeee.............
great we love you
this is interesting video
DI kinda like undermines what OOP actually should look like, I really hate it, the world was better before DI showed up :D
ApplicationComponent is no longer present
Endangerment[sic]
Great
Engagement!
You are providing misleading information. You complain that the binds annotation does not always work but:
At minute 2:52 you can clearly see how it says "inject interfaces with @bind" ( The @Binds annotation tells Hilt which implementation to use when it needs to provide an instance of an interface)
Then at minute 10:18 you try to implement an actual class and complaint it doesn't work.
2) Even of by some crazy reason you did not realize about point one. You start by saying you need to tell hilt how to build this instance yet on the bind gson example you request by parameter an instance of the same class you already know hilt doesn't know how to build. What where you expecting?
Difference between bind and provide its quite clear if you read the docs
engagement
U didn't sleep at nite.🤔🤔🤔