tags:

views:

88

answers:

2

I'm just starting to play around with Google Guice as a dependency injection framework and am attempting to retrofit it to a small to medium size project I recently wrote. I understand the basics of how Guice works, but am a bit vague on some of the approach details. For example:

1) Modules are used to define your bindings, which are then fed into the injectors. Do you tend to put everything into one module or do you tend to break things down into lots of smaller modules?

2) Do you have one injector at the top level which injects the entire object tree or multiple injectors dotted about which only inject those dependencies you really need to inject? I'm thinking here of my own code base which, of course, has many dependencies, but only a small handful which I need to control during testing.

3) I'm slightly stuck on the best way to get my system/integrations tests using test-environment-only modules instead of the production verions. This question is likely implementation specific, but I'm curious what methods people use. For reference, my app is a servlet based web app.

Any other pointers?

A: 

Take a look at the book Dependency Injection - it covers both Guice and Spring, so is very handing transitioning from one framework to the other. Definitely good if you already understand the principles behind IoC already.

Noel M
+1  A: 

1) Typically you'll break things down into multiple modules. One of the goals of Guice is to help make code modular, and that's what modules are there for. How you break this down is up to you (and obviously, you don't absolutely have to). One advantage of finer grained modules is that you can define modules within a particular package and make the classes that implement the interfaces package-private. Since the module is in the package, it can bind those concrete classes and they can be used for configuring the Injector (in another package). Additionally, you make your code more flexible when you can change how something is done by just changing out one module for another, rather than having to change code in a single monolithic module.

2) Yes, one injector at the top level injecting the whole object tree is the way things should generally be done. This comes back to the modules thing... use them to break dependencies down in to groups and use one injector.

3) Use a different entry-point class that configures the injector. For a standalone app, I'd have a different main class... for a webapp, I suppose you could make a separate GuiceServletContextListener for testing. Then you can replace whole modules with modules for testing, or use Modules.override to override a binding in a specific module, etc.

ColinD
Ah, I think i'm beginning to see the difference now. I stumbled across another post of yours which shed light on my confusion. Essentially, multiple injectors throughout your code is more akin to a Service Locator pattern rather than dependency injection. There's still more to this for me to get to grips with, but thanks for your answer, as it gives me a really good start.
Chris Knight