views:

42

answers:

2

I created a class that uses the the Java Executor API to create/manage a pool with fixed number of threads. Each thread needs a new instance of a particular object, and I would like to inject this object with Guice. For the moment I'm using a Provider which provides new instances of the object through its get() method.

But now this class has a dependency to the Provider, which is Guice specific, effectively coupling the code to the Guice framework. I would really like the class to be truly Guice agnostic, is this possible?

Just creating new instances of using the 'new' keyword is not an option, as this makes it impossible to replace those object by a mock implementation in the unit test.

Dependency injection is probably not suited for this and I would be better of creating a factory to get these objects?

+1  A: 

If you want Guice to inject your objects for you, your objects are going to be coupled to Guice. That's the way Guice works. You could get around using the Provider interface by creating your own Factory interface and injecting that, but you'll still have to have an @Inject somewhere which will couple you to Guice.

Personally I think you should reconsider your requirement of having 0 coupling to Guice, but if you absolutely have to be able to write classes that have no references to your DI container, you should look at something like Spring.

Mike Deck
Yea, I looked at the Spring lookup-method which use cglib to override a method at runtime, that comes pretty close to what I want.But it is not a necessity to make the class 100% Guice agnostic, I was just curious :)I guess I'll stick with the Provider.
nkr1pt
I'm not sure what you mean by "you're [sic] objects are going to be coupled to Guice." Guice can inject objects that are created and maintained completely outside of Guice (through the creation of a Provider).
erickson
@erickson, that is true, but then the parts of your code that are going to use that class either have to be coupled to the Injector or a Provider. I guess what I'm getting at is at the end of the day if you want to use Guice there are going to be parts of your code base that are coupled to it, so why is it so important that this particular Runnable class not be coupled to Guice?
Mike Deck
I see what you mean. Yes, at some level (usually a very high level, like when you are initializing your application), of course you are going to have to create a Guice `Injector` and get instances from it. When kicking off a new thread like this, there's a good chance to have that sort of direct dependency.
erickson
+2  A: 

One thing you may want to consider is building Guice from trunk and using that until Guice 3.0 is released. Then you can use JSR-330's javax.inject.Provider instead of Guice's.

Edit: Other than that, I'm generally of the opinion that coupling to the DI container (by importing something from com.google.inject, in this case) is less of an issue than people sometimes make it out to be. As long as you aren't depending on the details of how you get your dependencies (e.g. injecting the Injector all over the place) it's fairly easy to, say, change all places you injected Provider to take your own interface with a similar function instead. Depending on powerful features like scoping is where you really couple yourself to the container. I think that's fine as well though, given how much ugliness and effort they save you.

ColinD
I've done this and it works great. Only the module depends on Guice.
erickson