I was trying to add Dagger 2 to my android app.
As far as I understand, Dagger will construct my object(which I am trying to inject) as long as its' dependencies are provided(in a Module) or they are injected using some form of injection(constructor/method).
I would like to know if there's a distinction between when a dependency should be provided in a Module(say Application Module) vs when its' injected using a constructor injection, and if there is any rule of when I should do which?
Both are the same. Constructor injection basically eliminates the need to write a provider method. As a rule of thumb, I mostly use it for classes with a no-args constructor for easy injection, like Util classes.
There's no difference really. As long as Dagger knows how to construct an instance, that's all that matters.
The reason there are two ways to do it is that you don't always have the ability to use constructor injection, for instance if the class is part of a library that you are using but which you don't have the source (and so you can't add #Inject on one of the constructors).
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.
I am using Dagger 2, and I'm trying to understand how to use different configuration for testing.
If I use field injection, I can swap my Modules with fake Modules.
But for classes that have constructor injection, I can't figure out how to do it.
So, is this a reason to avoid constructor annotation? or is there a way to exchange such a class with a fake?
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.
There is one approach mentioned in http://www.vogella.com/tutorials/Dagger/article.html#connecting-consumers-and-providers and other approch without using Component here http://antonioleiva.com/dagger-android-part-2/.
First, please note that Dagger 2 and Dagger are not the same thing. If you read ObjectGraph you are probably reading about Dagger (1).
You can not use Dagger 2 without components. Components are the objects that hold your dependencies and know how to provide and inject them. I think the same holds true for Dagger 1 about their ObjectGraph. If you don't have the means to provide your dependencies, you can't use DI.
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