Guice injector.getInstance() - good practice?

albogdano picture albogdano · Oct 11, 2013 · Viewed 26.8k times · Source

Let's say I have two applications sharing the same library. This library contains common classes like DAOs, Utils, etc. Everything in the shared library is wired with Guice. My two apps depend on this library but do not have a direct dependency on Guice.

 ______    ______    ______
|      |  |      |  |      |
| APP1 |->| LIB  |<-| APP2 |
'------'  '------'  '------'

I currently use something like this:

static <T> Utils.getInstanceOf (Class<T> type);

which is simply a wrapper for:

injector.getInstance (Class<T> type);

But the guice docs say:

When feasible, avoid using this method, in favor of having Guice inject your dependencies ahead of time.

So what's the best way to provide dependency injection for the two apps without having to manually bind them in a Guice module?

Answer

Vladimir Matveev picture Vladimir Matveev · Oct 11, 2013

So what's the best way to provide dependency injection for the two apps without having to manually bind them in a Guice module?

There is no such way. You either embrace Guice totally or do not use it and pass your dependencies explicitly. Well, structuring your code in such way so you never directly create class dependencies, passing them instead through a constructor, also may be called 'dependency injection', but I'm sure this is not what you meant. If you do not want to use Guice in your apps, you won't be able to get anything better than getInstance(), which is ugly, especially because you're using static wrapper.

Ideally your library should provide a module which you can install via Guice.createInjector() in your applications, or, in the other way around, the library should provide an Injector instance which you can use in your applications by using createChildInjector() and providing application-specific modules. Slight modification of this approach is passing application-specific modules to the library so they will be used to create Injector. I have recently written Guice-based API over custom servlet-like interface which didn't support any kind of DI at all using the last approach, and it is working perfectly.

It is not at all hard to use Guice in servlet or Jersey environment. The latter, for example, has out-of-the-box integration with Guice (at least, in 1.x versions). Guice servlet extension is also very good and convenient. Just try it and see for yourself.