I'm trying to figure out dagger and having a hard time to grasp the concept of the object graphs.
I'm not new to the dependency injection paradigm, I used angular.js in JavaScript and prism in .Net. So I do understand the idea behind it.
What I can't seem to understand is whether the object graph should be actually a single graph, meaning one in all the app and all the dependencies should be injected from it or should I create one for each module.
I want to create an instance of a class with injectables, so should I use an existing object graph or create a new one?
Where is best practice to create multiple mudules ? Should I create object graph per module as a singleton? Create one object graph for all the app that every class should use? Or should I create a new object graph each time I need a new instance?
Thanks
Think of Object Graphs or Components (if using dagger2) as a way to scope objects. You mentioned you used .Net so I am assuming you are familiar with scoping. Rather than creating a graph for each module I would recommend creating an object graph for each scope. A common pattern is to have an Application scope and then "plus" the activity graph/component onto the Application scope. You can have 1 to many modules per component. Modules are more of a way to split dependencies into different files (even thought they may still be in same component). CodePath has a pretty good intro on Dagger including going into scopes as well as multiple modules per component. Best of Luck! https://github.com/codepath/android_guides/wiki/Dependency-Injection-with-Dagger-2
Related
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.
I am looking into MVP architecture Implementation in android.
I found too many ways(mention end of the question) to implement it in the android studio, but Still, I am confused.
Can someone help me to find the right answer of below questions.
What would be directory structure of Application in MVP?
Activity should be a Presenter or View?
Way-1
Way-2
What would be directory structure of Application in MVP?
There is no predefined structure for that. What makes your code readable or what structure you are following, you can use same for MVP also.
Activity should be a Presenter or View?
View is the UI layer which displays the data and notifies the Presenter about user actions. So Activity will always be a view.
If you are looking for a good example of MVP implementation, there is one GitHub Repo for MVP developed by Android itself. Which you should look into.
Where
todo‑mvp
Demonstrates a basic Model‑View‑Presenter (MVP) architecture and provides a foundation on which the other samples are built. This sample also acts as a reference point for comparing and contrasting the other samples in this project.
todo‑mvp‑clean
Uses concepts from Clean Architecture.
todo‑mvp‑dagger
Uses Dagger 2 to add support for dependency injection.
todo‑mvp‑rxjava
Uses RxJava 2 to implement concurrency, and abstract the data layer.
todo‑mvvm‑databinding
Based on the todo-databinding sample, this version incorporates the Model‑View‑ViewModel pattern.
todo‑mvvm‑live
Uses ViewModels and LiveData from Architecture Components and the Data Binding library with an MVVM architecture.
Though there are lot of implementations for an MVP architecture, all of them share a basic idea (or they should at least), which is separating business logic from your views (activities, fragments, dialogs). Why is that? Well, for two reasons mainly:
separation of concerns
Testability: your business logic is able to be tested if there is no android components involved.
About your questions:
What would be directory structure of Application in MVP?
There is no rule about that except that your MVP components should be identified. Here you have an article where I started with a package structure but then I found other more convenient.
Activity should be a Presenter or View?
Your activity (or fragment or whatever components in charge of showing view components) should be the one that implements your view.
My advice is that you should check multiples examples and see their advantages and disadvantages of each one, and try to define your own architecture from those which you will feel more comfortable with.
You can use either Activity or Fragment for View layer. This is because showing UI elements in android needs Context.
For the Presenter layer, you must make sure not to pass the Context to the Presenter via constructor or setter. If you needed Context in your Presenter for tasks other than showing the UI, such as writing to SharedPreferences, you can get it from your View (which is either Activity or Fragment). In this way, if the View gets destroyed or becomes null, there would no standalone null Context in the Presenter to cause leak issues.
If you want to know more about the MVP structure, I have written a very handy MVP library for android and explained its use in a sample app here.
MVP android sample example application
MVP Android Example used to explain how to use this pattern in our Android apps.
I have a couple of questions, since there is no decent documentation on Dagger 2. I am very new in programming, so the questions might be stupid
1) Is it ok to have only 1 component in application that consist of all modules.
2) It seems that you need to inject only from 1 component in the class or all of the components must provide all of the #inject objects.
3) For instance, if in my application I have 2 different objects in 2 modules of the same type but for different purposes and 1 singleton object for whole app.
How do I inject singleton object and one of my 2 different objects for the certain purpose. How Dagger will understand what exact object do I want.
When using Dagger, I found that I'm getting multiple instances of a singleton when I inject it wherever I need it. I've annotated the class and the provides method with #Singleton. Can anyone think of why this is happening?
Edit:
If it helps, I have followed the same structure for my app as the sample application in Dagger's GitHub (https://github.com/square/dagger/tree/master/examples/android-activity-graphs). I'm trying to get the Singleton in the base activity and a couple of third party classes provided using #Provides at the custom Application class. Is it because I'm plus-ing modules at each activity to the original object graph?
(PS : I'm new to Dagger and DI in general, so I'll be grateful if you could provide an explanation so that I may learn. Thanks.)
#Singleton, in Dagger 1.x, acts differently than you might think. The JSR-330 spec definition in the #Singleton javadoc is "one per graph" and that is how Dagger interprets it.
So if you have something that is marked as #Singleton, and it is materialized in your application graph (as opposed to a shorter-lifetime graph), then you get one instance per application.
If you have an item annotated #Singleton that's in the modules you use to configure your activity graph (i.e., that is obtained from the part of a graph specified by a module used in the plus() operation) then you will get one-per-activity-graph.
If you need something to be once-per-application, you need to make sure it gets created as a part of the application graph. You can do this in one of two ways. Either explicitly provide it with an #Provides method from your application module(s), or you can list it as a one of the classes in #Module(injects=...) in an application module.
(If you do not mark it with #Singleton than you will get one per injection site.)
So remember, the graph created by plus() is seen as a separate graph that points to the graph from which it was spawned, and wraps it, can access instances within it, but is not the same graph.
Note - Dagger 2.x improves this, and supports custom scoping annotations, though the mechanism is similar, with one graph (component) per scope annotation, with a parent/child relationship between graphs of wider/narrower lifetimes