Java dependency injection: Dagger 1 vs Dagger 2, which is better? - java

What are the advantages of Dagger 2 over Dagger 1?
So far I found (just) 2:
Dagger 2 allows you to use code obfuscation with proguard
Dagger 2 is faster (which is not much of an advantage when using it for android application but it is sure an important thing if you use it for some kind of server)
In the same time I found one big disadvantage: you cannot have module overrides (#Module(overrides = true)) in Dagger 2, which is largely annoying at least for me - it was very useful for unit test.
Are there other advantages / disadvantages?

Some advantages and disadvantages taken from https://blog.gouline.net/2015/05/04/dagger-2-even-sharper-less-square/ and http://google.github.io/dagger/dagger-1-migration.html:
Advantages of Dagger 2:
No more reflection - everything is done as concrete calls (ProGuard works with no configuration at all)
No more runtime graph composition - improves performance, including the per-request cases
Traceable - better generated code and no reflection help make the code readable and easy to follow
Supports method injection in addition to field and constructor injection which were the only two types supported by Dagger 1
Modules require less configuration than Dagger 1
Allows users to use any well-formed scope annotation. Dagger 1 only supported a single scope: #Singleton.
And disadvantages:
The inject() method now has a strong type association with the injection target. This is good for debugging, but it complicates a common practice of injecting from base classes (e.g. base activities, fragments etc).
Component implementation requires rebuilding the project to appear and any injection-related compile errors result in the class disappearing (i.e. not being generated).
Doesn't support overrides. Modules that override for simple testing fakes can create a subclass of the module to emulate that behavior. Modules that use overrides and rely on dependency injection should be decomposed so that the overriden modules are instead represented as a choice between two modules.
EDIT 2016/11/16: This is not a technical advantage, but Dagger 1 is now deprecated (as of September 15, 2016) and will no longer be actively developed. They recommend migrating to Dagger 2.

I wouldn't recommend having a look at toothpick.
As a co-author, I am obviously over biased, but yeah this one is far simpler to use, at least as fast in most cases than the daggers. And really the scope tree is a very very powerful way to develop more advanced features like recycling instances in scopes spanning on multiple activities.

Related

Android Dependency Injection using Dagger 2

I just started using dagger 2 for dependency injection in android. The way i'm using it now i made sure i don't have
new Class();
but i have a feeling i'm over using dependency injection. I inject any thing that needs an instance. is this right? or are there set of things i can inject or i can inject everything
It is very easy and common to overuse dependency injection, and I wouldn't endorse the practice of "inject anything that needs an instance". However, you'll need to decide which aspects fall into which group.
One distinction I've seen drawn is "injectables" vs "newables", as in this oft-cited article by Miško Hevery (also on the Google Testing Blog), this article by Giorgio Sironi, and this Dagger 2 StackOverflow answer.
You may want to weigh the advantages of dependency injection, which include:
ability for the environment to substitute out implementations, particularly in testing against unwritten, heavy, or nondeterministic implementations
insulation from your dependencies' dependencies, which may change and evolve independently
...against the costs, which include:
difficulty in telling which implementation may be supplied
additional Provider classes and instances, which may be expensive on embedded/mobile platforms
complex syntax and build steps to handle mixing constructor parameters and factories, such as through AutoFactory
Value and model objects, which are unlikely to have multiple or risky implementations, are often squarely in the newable camp; interconnected and interdependent services are often far into the injectable camp. For lightweight services and utils, you'll need to identify the benefits provided above and draw the line based on the benefits you need.

Proper Class Construction: Using Multiple Hard Dependencies

I'm trying to integrate Single Responsibility Principle into my Java code by refactoring large classes (2000+ lines) into smaller, cohesive classes (~200 lines). However I'm confused how to properly reduce coupling between classes, since certain classes seem bound to be create multiple "hard dependencies" via the new keyword.
I'm using dependency injection via constructors primarily, followed by setter methods, or methods which accept the dependency as a parameter and use it amonst other logic within the method body (not just a simple this.val = val; setter.
IntelliJ's automatic refactoring instantiates this newly extracted class and passes (injects) it with a this reference to the LoadController. If I have to refactor a 2000 line class, of course this auto-instantiation + injection will occur each time I extract a new class out. The following LoadController is a JavaFX controller class for the program's main stage, which acts as the starting point for various features:
public class LoadController{
private final DBConnection dbConnection = new DBConnection(this);
private final UpdateLabels updateLabels = new UpdateLabels(this);
private final OpenCloseMenu openCloseMenu= new OpenCloseMenu (this);
private final CreateVBox createVBox= new CreateVBox (this, dbConnection);
private final ...
private final ...
}
Is this wrong? My understanding is that large, separate functions should be in their own class ... BUT some classes must have multiple hard dependencies like above, in order to "guide" the flow of logic between the use of various other classes.
If you are doing dependency injection into JavaFX controllers, you might want to look into using something like Gluon Ignite to assist you.
Gluon Ignite allows developers to use popular dependency injection frameworks in their JavaFX applications, including inside their FXML controllers. Gluon Ignite creates a common abstraction over several popular dependency injection frameworks
The injection framework you choose to use (e.g. Guice or Spring) will be responsible for creating the injectable components (e.g. you don't invoke new) and injecting the relevant references into your code, (e.g. you don't need to write dbConnection = <some value>). The injection framework will have extensive documentation and blog articles on how it works and how it may best be used, so full discussion of that is outside the scope of this answer.
An alternate to Gluon Ignite is afterburner.fx, which is similar but uses a small custom implementation for #Inject, so is more lightweight (and a little less powerful), then the more established dependency injection frameworks (very simple to use though).
This is just one option, there are other ways you can handle this, but seeing as you state that you wish to perform dependency injection with JavaFX, it seems to make sense of proven frameworks to do this rather than try to roll your own implementation.
some classes must have multiple hard dependencies like above, in order to "guide" the flow of logic between the use of various other classes.
Using something like Guice you provide a module that defines bindings between interface types and implementations. These bindings tell Guice how to construct the dependencies, so you don't need to hard code the dependencies in your classes. See the BillingModule in the Guice getting started guide for a module example. If you need multiple instances of injectable objects, you can use Providers in Guice. Spring has similar concepts, but different names.
Deciding on whether or not to use a dependency injection framework is a tradeoff between the work you would need to do if there was no injection framework vs the additional time and complexity of integrating the framework into your application. so the decision of whether or not to use one needs to be an architectural decision that you make, there is not a generic right or wrong answer for every application on whether use of such frameworks is justified.
I decide that using an injection framework is superfluous for my requirements, then I am not doing anything inherently incorrect by having multiple hard dependencies in some classes, as shown above?
Well the dependencies need to be defined somewhere. Either in an inferred or centralized location such as dependency injection systems use or local to given classes as you might determine from a traditional responsibility driven design approach. So you are not necessarily doing anything wrong by having hard dependencies. Abstract decoupling patterns such as dependency injection aren't always required.
The trick is determining what dependencies to have where and how to manage them. Often it is just obvious and falls out naturally from the problem domain, sometimes techniques such as CRC modeling can help structure dependencies.
Related article:
Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler.
My assumption is that I can refactor my large classes into smaller, cohesive classes with some of these classes having multiple hard dependencies, using new.
Yes, you can certainly do that.
Can an injection framework be integrated later on in a project's life, rather than early on when it may not be required yet?
Yes it can. It will be a bit of work to do so, but if the application is well structured, not all that difficult. It is more difficult to go the other way and try to remove usage of a dependency injection framework from applications and libraries that are already based on it.
Related:
Passing Parameters JavaFX FXML

How do I add an unknown amount of unknown modules in Dagger 2?

I have several modules that I don't know at compile time (think "plugins"). They all implement a "tag" interface MyModule: public interface MyModule {}
I've instantiated them thanks to ServiceLoader and #AutoService.
How do I add them all to my component builder?
The Dagger 2 authors seem to think that this question is relevant to StackOverflow. I don't believe that it is, because it looks like a missing use case, but well, I give them the benefits of the doubt here and post it.
I know I could use Guice or Dagger 1, but as said in the ticket to the Dagger 2 team; I don't want any reflection (bar ServiceLoader), and Dagger 1 is now deprecated. Also, recommends switching to Dagger 2 (which is why I'm trying to upgrade my Dagger 1 project to Dagger 2).
This is impossible as it stands, and is also outside of Dagger 2's charter. See the opening sentence of the project overview (emphasis mine):
Dagger is a fully static, compile-time dependency injection framework for both Java and Android.
When you're asking for your object graph to handle arbitrary marker-interface modules, you're precluding Dagger from knowing which #Provides methods it will have access to, which deprives Dagger of the ability to inspect and wire up your component at compile time. So, for Dagger to support your use case as you've stated it, it would have to reverse a number of core architectural decisions and advantages of compile-time inspection and code generation. Though I'm not on the Dagger team, I imagine this would make it a poor fit for the foreseeable future, which I imagine is part of the reason your issue was marked Working As Intended.
That said, there are number of ways you could use multiple coexisting components (one per plugin) to use static analysis and code generation in the core application, while supporting an arbitrary number of plugins. For instance, if your plugins have a predictable set of dependencies, you can create a new PluginModule(PluginFactory... factoriesToSupport), which would offer a #Provides Set<Plugin> createPluginSet(Dep1 dep1, Dep2 dep2) to iterate across the plugin factories and return you a set of plugins. In addition, if the plugin dependencies represent a large proportion of your top-level Component and your build graph supports it, you could inject the Component itself into the #Provides method, and then let your individually-built PluginFactory instances defer to their own (static-analyzed code-generated) Dagger components to produce the plugin instances. In short, as long as you're in Dagger, you'll need to play by Dagger's compile-time analysis rules, but within those constraints you can still likely come to a workable solution.

how does Spring (DI) help in development by wiring the components?

I have learned Spring for quite some time (just learn, without actual hands-on experience on real project). In my understanding, Spring provides a DI frameworks, which allows centralize way of connecting / wiring all the classes in one place. The classes themselves do not compose / instantiate other components.
I can understand, DI allows easier unit-testing for each component as they are depending on interface.
My question is, why does wiring all the classes in centralize way (externally) helps in development process (besides testing), compared to traditional way (each class instantiates another class).
This link on DI explains it pretty well:
http://en.wikipedia.org/wiki/Dependency_injection#Motivation
The primary purpose of the dependency injection pattern is to allow selection among multiple implementations of a given dependency interface at runtime, or via configuration files, instead of at compile time. The pattern is particularly useful for providing "mock" test implementations of complex components when testing; but is often used for locating plugin components, or locating and initializing software services.
Unit testing of components in large software systems is difficult, because components under test often require the presence of a substantial amount of infrastructure and set up in order to operate at all. Dependency injection simplifies the process of bringing up a working instance of an isolated component for testing. Because components declare their dependencies, a test can automatically bring up only those dependent components required to perform testing.
It improves the quality of your code by reducing coupling between classes.
If a class instantiates an instance of another class, then there is a dependency directly between the two classes (=tight coupling). So for example, if Class A has-a relatoinship with Interface B, if Class A handles the instantiation of the Interface B, then Class A must specify a concrete implementation to instantiate and those classes become tightly coupled.
Lets say we have the following interface:
interface B{}
and then the following Class
class A{
private B b = new BImpl();
...
}
In the above example (without DI), Class A has an explicit dependency on BImpl, which means if you ever want to use a different implementation of B then you also have to change Class A.
DI (and loose coupling in general) aims to remove these kind of dependencies and have a code base where changes to one part of the code do not "ripple" through the entire application requiring lots of changes. The above example is pretty trivial, but if you have a medium to large size codebase with tight coupling this problem can get pretty bad.
why does wiring all the classes in centralize way
Centralized configuration is an implementation detail rather than part of DI. Guice for example can spread the configuration about a bit (I've not used Spring in anger so I can not comment on it).
why does wiring all the classes ... externally
As this allows you to change the implementation. DI is not the only way but it is the most popular. Factories and Service Locators are the main alternatives. Without some way of swapping out the implementation testing becomes near impossible.
development process (besides testing)
Testing is a very important part. It alone is a good reason to separate creation and use.
Unlike the other two methods above and direct initialization DI also makes the dependencies visible (esp. ctor injection) this can help other users of the class. By making the dependencies so visible it can be used to give you a warning when your class is doing too much (as it will require a lot of dependencies).
DI concept is independent of spring. Dependency Injection is possible even without using Spring. I.e. manually injection of dependency is also possible.
Please refer java example given on wiki:- http://en.wikipedia.org/wiki/Dependency_injection#Manually_injected_dependency
DI main purpose is loose coupling.
Spring provides IOC (Inversion Of Control). When we use spring to inject dependency using the Spring IOC, we get features like:
1) Loose coupling, reduce time to add new feature. Code to interface will provide this. Add new service which complies to interface and which can be replaced in bean configuration.
2)No need to change code/compile required while changing dependency.
3)Easier and fast testing. Hence, can cover more cases in same time frame which leads to good product.
4) Spring provides lots of different templates to make developers life easier. These all templates are using DI/Ioc concept. Leads to faster development cycle. Such templates are available for batch processing, JMS, JMX, JDBC operations and many more.

Mocking / Testing a core object in my system

I've been asked to work on changing a number of classes that are core to the system we work on. The classes in question each require 5 - 10 different related objects, which themselves need a similiar amount of objects.
Data is also pulled in from several data sources, and the project uses EJB2 so when testing, I'm running without a container to pull in the dependencies I need!
I'm beginning to get overwhelmed with this task. I have tried unit testing with JUnit and Easymock, but as soon as I mock or stub one thing, I find it needs lots more. Everything seems to be quite tightly coupled such that I'm reaching about 3 or 4 levels out with my stubs in order to prevent NullPointerExceptions.
Usually with this type of task, I would simply make changes and test as I went along. But the shortest build cycle is about 10 minutes, and I like to code with very short iterations between executions (probably because I'm not very confident with my ability to write flawless code).
Anyone know a good strategy / workflow to get out of this quagmire?
As you suggest, it sounds like your main problem is that the API you are working with is too tightly coupled. If you have the ability to modify the API, it can be very helpful to hide immediate dependencies behind interfaces so that you can cut off your dependency graph at the immediate dependency.
If this is not possible, an Auto-Mocking Container may be of help. This is basically a container that automatically figures out how to return a mock with good default behavior for nested abstractions. As I work on the .NET framework, I can't recommend any for Java.
If you would like to read up on unit testing patterns and best practices, I can only recommend xUnit Test Patterns.
For strategies for decoupling tightly coupled code I recommend Working Effectively with Legacy Code.
First thing I'd try to do is shorting the build cycle. Maybe add in the options to only build and test the components currently under development.
Next I'd look at decoupling some of the dependencies by introducing interfaces to sit between each component. I'd also want to move the coupling out in the open most likely using Dependency Injection. If I could notmove to DI I would have two ctors, on no-arg ctor that used the service locator (or what have thee) and one injectable ctor.
the project uses EJB2 so when testing, I'm running without a container to pull in the dependencies I need!
Is that without meant to be a with? I would look at moving as much into POJOs as you can so it can be tested without needing to know anything EJB-y.
If you project can compile with Java 1.5 you shoul look at JMock? Things can get stubbed pretty quickly with 2.* version of this framework.
1.* version will work with 1.3+ Java compiler but the mocking is much more verbose, so I would not recommend it.
As for the strategy, my advice to you is to embrace interfaces. Even if you have a single implementation of the given interface, always create an interface. They can be mocked very easily and will allow you much better decoupling when testing your code.

Categories

Resources