i just tinkered around with Google Guice for Dependency Injection and started integrating it into my existing application. So far, so good. I have many classes which need, beside their dependencies, Strings, DataSources, et cetera. I know there are NamedBindings, but i really do not want to create an annotation for every simple String i have to pass to the constructor for each class. Then, there is a thing called AssistedInject, creating Factory implementions for me. Wow, but i still have to define the interface of the factory. Thats okay for classes which DO HAVE dependencies, but what about this example class:
public class FooBarClass {
public FooBarClass(String name, String anotherOne) {
// Some stuff
}
}
There are cases where i am in doubt how to use Guice or, more generally, DI the right way. "Often i hear: XYZ Framework is the new new." But this implicit that i have to create every instance with the DI framework.
What if i need only one instance of this class? This class has absolutly no dependencies beside two Strings. Think about a Shutdown Hook which will be instanciated only once and passed to the JVM as my Shutdown Hook. Should i create this instance with Guice? This looks very dumb to me, because there is nothing to inject, but i have to write a factory interface to pass Guide both parameters and have to create an interface for my FooBarClass to use DI.
The same thing applies to a case where i need multiple instances of this class. No dependencies, but i have to create a bunch of boilerplate code to get nothing out of it. This seems wrong to me.
So, how i am supposed to use DI and/or Guice?
Thanks a lot!
Using Guice In each of your constructors that need to have something injected in them, you just add an @Inject annotation and that tells Guice to do it's thing. Guice figures out how to give you an Emailer based on the type. If it's a simple object, it'll instantiate it and pass it in.
Spring allows you to omit the @Autowired annotation when there's only one constructor. Guice allows binding to a Provider, as well as injecting a Provider of your class, even when your class has no Provider binding.
To my knowledge, Dagger does generate code, while Guice and Spring rely on runtime processing, thus Dagger works faster, but requires more work on programmer side. Because of performance edge it's good for mobile (Android) development.
It might help to split dependencies from data.
UserAuthenticator
, PaymentHandler
, and EmailGateway
.Date
, a Map<String,InetAddress>
or even a Customer
. These are simple, in-memory domain objects.DI is naturally best suited for the dependency side of things. You should continue to use new
for your data model classes.
if you are creating multiple instances such as individual Customers, it does not make sense to inject them. what makes sense is to create a CustomerFactory which may be @Singleton scope that can create Customer instances with all its dependencies.
Inject a dependency if you want to ignore (isolate) its complexity when testing a particular class. If the class is just a data holder, its code is trivial (get, set, equals). You don't need to mock it when testing the target class, so injecting the data instance is overkill (and usually hard). If the code is not trivial, the class is more than a data holder, and you should inject and mock it on unit tests.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With