Hi Jae,
BTW i am still finding my away around with Guice and am by no means an
expert so providing use cases like this is very valuable.
I notice that from here:
http://code.google.com/p/google-guice/source/browse/trunk/src/com/google/inject/Injector.java
/**
* Returns all explicit bindings.
*
* <p>The returned map does not include bindings inherited from a
{_at_link #getParent() parent
* injector}, should one exist. The returned map is guaranteed to
iterate (for example, with
* its {_at_link java.util.Map#entrySet()} iterator) in the order of
insertion. In other words,
* the order in which bindings appear in user Modules.
*
* <p>This method is part of the Guice SPI and is intended for use
by tools and extensions.
*/
Map<Key<?>, Binding<?>> getBindings();
So the Injector.getBindings does not return bindings from the parent
injector (if any). It was not the intention to ignore bindings of the
parent.
So IIUC the fix would be to traverse up the injector hierarchy, to
find the injector that contains an explicit binding for the class:
private Injector findInjector(Key<?> key) {
Injector i = injector;
while (i != null) {
if (i.getBindings().containsKey(key))
return i;
i = i.getParent();
}
return null;
}
public IoCComponentProvider getComponentProvider(ComponentContext
cc, Class clazz) {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.fine("getComponentProvider(" + clazz.getName() +
")");
}
Key<?> key = Key.get(clazz);
Injector i = findInjector(key);
// If there is no explicit binding
if (i == null) {
// If an @Inject is explicitly declared
if (!isInjectPresent(clazz)) {
return null;
}
...
Would that work for you?
Would it be possible to provide a simple test case that represents
your use-case and i can add that as a unit test.
Paul.
On May 10, 2009, at 2:23 PM, Jae Lee wrote:
> Hi all,
>
> I've got a newbie question really...
>
> From brief look through GuiceComponentProviderFactory source code
> (1.1.0.ea), it looks like if you built GuiceComponentProviderFactory
> with an Injector Guice Scope is ignored for an object explicitly
> bound by its parent Injector... is that an intended behaviour?
>
> In my current project, we've got an Application and many Components
> underneath. Component being loosely related resources, defines an
> independent context. It is achieved by having a child Injector for
> each Component under an Application.
>
> Naturally we would have common class/object bound in Injector in
> Application (a bit like application scope) and component specific
> class/object bound in child Injector in Component (a bit like
> component scope)
>
> It looks like GuiceComponentProviderFactory uses
> GuiceInstantiatedComponentProvider which ignores Guice Scope, for
> any explicitly bound class in parent Injector. Which is bit of
> problem when it comes to Singleton scoped class.
>
> Injector.getBinding(key) does return binding from parent Injector if
> possible then fall back to Just In Time binding with Scopes.NO_SCOPE.
>
> Given that even for Just In Time binding, there's a scope (NO_SCOPE)
> that can be mapped to Jersey, is it possible to use
> GuiceManagedComponentProvider all the time? Would that makes it
> functionally different from current implementation? Benefit would be
> that then it can support Singleton Guice object in parent Injector
> properly.
>
> regards
> J