I have been learning Dagger 2 for a week and in the tutorials I read, most of them wrote that it is preferable to use Constructor injection over Field and Method injection.
I am confused and wanted to make clear, when should I be using Constructor injection, and when Field and Method injection.
Thanks in advance.
I can't say this is the definite answer, but I'd like to share my opinion. I prefer constructor injection because you're forced to create the object by fulfilling its dependencies. In other words you'll never end up in the situation that you call an object's method and because some dependency wasn't set, you get a null pointer exception (unless you set it as null on purpose in which case you're asking for it). I tend to always use constructor dependency injection everywhere.
That said, sometimes it's simply not possible. In Android for example the Activities are created by the system and hence we don't usually have our own constructor to call and pass in the dependencies. Here I often use field dependency injection. I do this because there's a lot of tools out there that help you out with this.
A third options is through setters. Personally I never used it. Not entirely sure where this would be needed. Perhaps when the dependency has to change at run time? Not sure.
Related
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.
What's the point of using Dagger2 and Kotlin ?
Dagger2 docs says:
"Constructor injection is preferred whenever possible because javac will ensure that no field is referenced before it has been set, which helps avoid NullPointerExceptions."
The main reason why Kotlin exists is to provide null safety.
So is it worth to use Dagger2 with Kotlin ?
This quote (which I don't directly see in the docs, but never mind) says that one way of using Dagger (constructor injection) is more null-safe than another (method injection).
It doesn't say anything about using Dagger to provide null safety compared to not using Dagger.
If you use Dagger's constructor injection with Kotlin, your properties will be normal non-nullable ones; if you use method injection, you'll need to make them nullable or use lateinit. So constructor injection still provides more null-safety than method injection when used with Kotlin.
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.
I have a poroject that was developed by other developer. There are a lot of public static fields, arrays and etc. And this public static fields are being called like from everywhere(every class). It causes a lot of crashes. I need some architectural advice. Anyway, im gonna need to refactor all this code. How can i avoid using static fields? I know how to do it using interface, espessially when dealing with activity-fragment communication. Maybe you can suggest some libraries for this purposes?
You can use Dagger 2 for dependency injection.
Introduction from http://code.tutsplus.com/, also this is a very good tutorial for using dagger.
When you have an object that needs or depends on another object to do its work, you have a dependency. Dependencies can be solved by letting the dependent object create the dependency or asking a factory object to make one. In the context of dependency injection, however, the dependencies are supplied to the class that needs the dependency to avoid the need for the class itself to create them. This way you create software that is loosely coupled and highly maintainable.
Also check this tutorial too for better understanding.
I'm going through androidannotations cookbook and I can't find way to inject dependencies to Bean via constructor.
Is it possible at all with this library? I have everything else up and running, but I just can't fix this single problem :/
AndroidAnnotations does not provide this feature currently. Setter injection maybe added in the next release.
Use field injection, if possible.