Details
-
Type: Bug
-
Status: Open
-
Priority: Major
-
Resolution: Unresolved
-
Affects Version/s: 2.11
-
Fix Version/s: None
-
Component/s: PicoContainer (Java)
-
Labels:None
-
Testcase included:yes
-
Number of attachments :
Description
I think I found a bug in PicoContainer's ProviderAdapter:
If I use a Provider, the class of the provider is used during reinjection and not the type that's being returned by the provide method of the Provider. The corresponding lines of code are:
public Object getComponentInstance(PicoContainer container, Type into) throws PicoCompositionException { return new Reinjector(container).reinject(key, provider.getClass(), provider, properties, new MethodInjection(provideMethod)); }
I guess this should rather be
public Object getComponentInstance(PicoContainer container, Type into) throws PicoCompositionException { return new Reinjector(container).reinject(key, key, provider, properties, new MethodInjection(provideMethod)); }
Also, since ProviderAdapter takes Object and not Provider, you might want to set the Provider interface to deprecated since it's no longer needed.
Test case!
@Test public void providerTest() { DefaultPicoContainer container = new DefaultPicoContainer(); ProviderAdapter adapter = new ProviderAdapter(new BlorbProvider()); container.addAdapter(adapter); assertNotNull(container.getComponent(Blorb.class)); } public static class BlorbProvider { public Blorb provide() { return new Blorb(); } } public static class Blorb {}
Expected result: Returns a Blorb. Actual result: java.lang.ClassCastException: com.eaio.concurrent.DynamicBlockingQueueTest$BlorbProvider is not a com.eaio.concurrent.DynamicBlockingQueueTest$Blorb
Oh, and you'll want to change MethodInjection from
if (injectionMethod.getDeclaringClass().isAssignableFrom(componentImplementation)) {
to
if (injectionMethod.getReturnType().isAssignableFrom(componentImplementation)) {