Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency Injection with Guice: Something that isn't covered by any tutorial

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.

Only one instance is required

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.

Multiple instances are required

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!

like image 920
Malax Avatar asked Jun 24 '09 13:06

Malax


People also ask

How does dependency injection work Guice?

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.

Is Guice better than Spring?

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.

Is dagger better than Guice?

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.


3 Answers

It might help to split dependencies from data.

  • Dependencies are often services: databases, clocks, and RPC stubs. Plus all of the application code layered on these: UserAuthenticator, PaymentHandler, and EmailGateway.
  • Data is just that: a 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.

like image 174
Jesse Wilson Avatar answered Nov 15 '22 09:11

Jesse Wilson


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.

like image 20
Andreas Petersson Avatar answered Nov 15 '22 10:11

Andreas Petersson


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.

like image 41
Fernando Avatar answered Nov 15 '22 08:11

Fernando