I have been using Dagger for a while and now I'm starting to migrate to Hilt, but I don't understand the benefits of injecting Activity and Fragment.
In Dagger, it is AndroidInjection.inject(this) and something like HasActivityInjector
Sorry if it was a stupid question.
It is not a benefit, it is a constraint imposed by Android. Activities and Fragments are instantiated by Android, not by the developer or the DI framework, and as such, they require special treatment. It is the same in Dagger actually.
In Hilt you don't need to write that code manually anymore, you can just annotate the Application, Activity and Fragment using special notations, the library will take care of generating the corresponding code.
Related
The idea behind dagger-android is to reduce the boilerplate needed to inject objects. To be even more specific, the idea is to reduce that boilerplate code in Fragments, Activities or any other Android framework classes that are instantiated by the OS.link
So, here as i made the bold text, what are the boilerplate code in android and how dagger2 reduce it?
I think you got it wrong Dagger does not meant to remove boiler plate code (It does in a way but it certainly not build for that purpose). That's what a library serve it perform the all the heavy lifting and provide us easier ways to implement the feature .
The feature dagger provide is Dependency Inversion principle its the D from SOLID principle .
Dagger is a Dependency injection framework which takes care of providing dependencies which the scopes provided its annotation base so its runtime safe. Its maintains a Dependency Graph of whole application the dependency we provides in our modules and inject them as they needed . That's all it does So yeah now you do not have to create objects in Activity/Fragment if you inject them if that's what you call boiler plate then you won't need it anymore . But IMO its not a boiler plate . Dependency Inversion principle Also make it easier to write code in TDD fashion.
You can build your own DI module if u don't want to use Dagger but why?
In Clean Architecture, Robert Martin says:
It is in your Main component that dependencies should be injected by a
Dependency Injection framework. Once they are injected into Main, Main
should distribute those dependencies normally, without using the
framework.
Martin, Robert C.. Clean Architecture (Robert C. Martin Series) (p.
232). Pearson Education. Kindle Edition.
However, Dagger doesn't work this way. Once you set up your dependencies in your application, you still need to depend on it as a framework, e.g. write #Inject annotations to get the dependencies into your classes. There is no way to 'distribute these dependencies' normally, by which I assume he means passing them through a constructor?
Can anyone help clear up my understanding and how best to use Dagger with a Clean style?
On Android, exactly following the advice you quoted from Robert Martin is rather difficult.
This is because there is no precise main entry point. Application, Service and Activity are quasi-entry points as your app will start with the OS instantiating one of these.
However, you don't have control over the constructor or anything really before the lifecycle callbacks. Hence, Dagger 2 on Android has had to rely on manually calling requesting a Component and calling Component#inject() inside lifecycle callbacks quasi-entry points.
However, there have been some measures to address this problem. Dagger-Android goes some way to address this by making you depend on AndroidInjector rather than some series of calls to the Application in order to retrieve the Component manually.
Even further, there is now FragmentFactory that allows control over the constructor of a Fragment, making Fragments amenable for constructor injection. If we use this then we have gone some way to following Robert Martin's advice.
To clarify the original quotation, I believe Robert Martin means that classes apart from the component root should not be polluted with logic for obtaining dependencies (e.g., by reaching into the Application, pulling out the Dagger Component). He is not prohibiting the use of the #Inject annotation which is lightweight meta-data (part of JSR-330) that simply marks a constructor as a site for injection.
In summary, yes - the current way of using Dagger 2 on Android doesn't exactly comply with Robert Martin's excellent recommendation. Nevertheless, this is a known problem and some progress has been made towards solving it.
I saw this question, but it was from the point of testability.
In my case, I see Dagger as an additional complexity for code (create #Provides methods, inject methods, remember all the right annotations). Should I still use Dagger if I just want to inject singletons like SharedPrefUtils? Is it really faster for this case?
Dagger was not made for creating Singletons and if creating a singleton is the reason you want to add Dagger to your project, then its an overkill. Dagger is a dependency injection framework that helps make the process of providing and injecting dependencies easier in a complex project. The #Singleton would help you ensure that only a single instance of a class is created when satisfying your dependencies it is not an alternative to the Kotlin object, they could even be used together. So like other answers and comments suggest if you have a small project and you could use simple design patterns like Singleton, Factory, and Abstract factory pattern.
Dagger is a dependency injection framework. For very simple applications, you can go with manual injection which will save you time because dagger can be difficult to set up and work with from the beginning. However, if you are planning on a production application which has a very long life span and will contain multiple UIs and multiple classes, then you are definitely going to need a dependency injection framework or strategy along the line.
There is an alternative for Kotlin which is Koin. Koin works more like a Service Locator and is easier to set up than Dagger but I will prefer dagger because it has survived the test of time.
It is up to you whether you want to use automatic dependency injection or manual injection so in the end you weigh your options and see what best fits your use case.
What's the difference between Subcomponents and Dependent-Components with specific scope in action? What's pros or cons of every one?
My Story: Recently I decided to stop using dagger-android and completely switched to traditional dagger for dependency injection in the whole of my project. Do you have any recommendations for creating component/subcomponent per fragment/activity?
If you create sub-component, all your component's dependencies will get available in your sub-component too.
You can access sub-component only via parent component instance.
The sub-component, scope is considered smaller than that of its parent component. So, your parent component and sub-component can't use the same scope annotation.
If you create dependent-component, then you have to explicitly expose dependency in your parent component. Then only, the child-component can use it.
You can use dependent-component directly, but you'll have to provide instance of parent component to build a dependent-component.
Get more details from these videos: https://www.youtube.com/playlist?list=PLrnPJCHvNZuA2ioi4soDZKz8euUQnJW65
Just watched an interview, and the guy said that the downside of Subcomponents is that if you change anything inside them, the whole AppComponent gets regenerated (and in big codebases that can be very slow), while Dependent-Components are separate entities.
Will research that more and correct the post if it is wrong.
It seems to be impossible but I can't find it written explicitly. Is there a clear reason for that ?
Thanks
That's not possible. A component can either inject everything at once or the compilation will fail with a cannot be provided error, listing what it's missing.
After all you can't partially call a constructor (if using constructor injection) and also partially injecting fields would be rather indeterministic about which objects were injected when, how, or with which scope. If both components could supply a dependency, which should provide it? Do you create and inject the object twice? What if another object depends on it in the other component? It would create more confusion than any good it could do and provide a source for a lot of errors and unexpected behavior.
Only one component can be used to inject inside a given class. You can have several subcomponents dependencies installed on it though.