0

Consider I have a service called FileSystem, and that this FileSystem is used by various classes throughout the application. Typically, the service is acquired via some static class method ServiceLocator.getService(FileSystem.class)

Now consider I have a class Game, that depends on the FileSystem object to open up some UI resources. The game will also construct a world, using a WorldFactory. The WorldFactory also requires the FileSystem service.

Here is where I encounter the problem, I construct a new instance of WorldFactory - which requires an instance of FileSystem to be injected into it. However, Guice will not inject into objects it has not constructed. So WorldFactory is left without a FileSystem injected into it.

So I could pass a FileSystem object to the WorldFactory but then in essence Guice hasn't solved any of my problems and I have come to realize I haven't been using Guice correctly because I can do all of this without it?

So then you get an odd instance where the constructor of a game entity requires that you pass an instance to the AudioSystem to it which it can play audio through. It just gets very messy with all these objects/services being explicitly passed around.

Thanks. I'm still new to guice and trying to figure out how to use it.

1

Both Game and WorldFactory class would have FileSystem as their dependencies. Below is an example of dependency injected through a constructor (it is also possible to inject them directly into fields):

@Inject
public Game(FileSystem fs) { }

@Inject
public WorldFactory(FileSystem fs) { }

You could then write a provider inside one of your modules that would construct and return a new FileSystem instance:

@Provides
FileSystem provideFileSystem() {
    return ServiceLocator.getService(FileSystem.class);
}

Once you treated other services similarly, you will be able to completely remove your reliance on ServiceLocator, moving the service-creating code directly into providers.

So then you get an odd instance where the constructor of a game entity requires that you pass an instance to the AudioSystem to it which it can play audio through. It just gets very messy with all these objects/services being explicitly passed around.

Not only this is not messy, this is the whole point of dependency injection. The thing is, however, that you should never explicitly pass all those instances manually. Instead, you can have Guice reconstruct the dependency graph from them and construct all necessary, intermediate objects (or obtain them in any other way you specify in your providers). On your side, creating the final object is just a matter of calling Injector.getInstance(Foo.class) -- it's up to Guice to figure out how to satisify the dependencies.

  • This really clarifies my understanding of how to use guice. I was very confused about what it does but now I see how I can bootstrap the entire application using it. It definitely requires some thought adjustment. – Jeremy Jun 24 '14 at 4:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.