Details
-
Type: Improvement
-
Status: Closed
-
Priority: Major
-
Resolution: Fixed
-
Affects Version/s: None
-
Fix Version/s: 2.9
-
Component/s: PicoContainer (Java)
-
Labels:None
-
Testcase included:yes
-
Patch Submitted:Yes
-
Number of attachments :
Description
Right now FactoryInjector can make decisions about the object to fabricate based on the Type of the target component. Sometimes several components of the same type can in the same container using distinct keys. When FactoryInjector is used to fabricate a dependency (logger or configuration object) for these it would be useful to provide different dependency to each of these components. This is impossible with the current design. However this feature can be introduced in fully backward compatible and non-invasive way.
Here's the test case extracted from the patch:
public class FactoryInjectorTestCase { // ... private static class KeyAwareSwedeFactoryInjector extends FactoryInjector<Swede> { public Swede getComponentInstance(PicoContainer container, final Type into) throws PicoCompositionException { return getComponentInstance(container, into, null); } public Swede getComponentInstance(PicoContainer container, final Type into, final Object targetKey) throws PicoCompositionException { // Mauro: you can do anything in here by way of startegy for injecting a specific logger :-) return new Swede() { public String toString() { return "Swede for " + ((Class) into).getName() + " " + targetKey; } }; } } @Test public void testThatFactoryCanUseTargetComponentKey() { MutablePicoContainer container = new DefaultPicoContainer(new MultiInjection()); container.addComponent(String.class, "foo"); container.addComponent("turnip1", Turnip.class); container.addComponent("turnip2", Turnip.class); container.addAdapter(new KeyAwareSwedeFactoryInjector()); Turnip turnip1 = (Turnip)container.getComponent("turnip1"); Turnip turnip2 = (Turnip)container.getComponent("turnip2"); assertNotNull(turnip1); assertNotNull(turnip2); assertNotSame(turnip1, turnip2); assertNotSame(turnip1.getSwede(), turnip2.getSwede()); assertEquals("Swede for " + Turnip.class.getName() + " turnip1", turnip1.getSwede().toString()); assertEquals("Swede for " + Turnip.class.getName() + " turnip2", turnip2.getSwede().toString()); } }
The patch has been created against 2.8.3 release, and it applies cleanly against trunk as of Jun 23rd 2009 / revision 5434.
All tests pass cleanly.
No changes are required to existing implementations of FactoryInjector interface within pico codebase or elsewhere.
Implemented slightly differently:-
http://fisheye.codehaus.org/changelog/picocontainer/java/2.x/trunk/pico?cs=5435
The main PicoContainer API has not changed, but there's a slightly different rule-set for implementors of FactoryInjector
I'd be interested in knowing your real need for this Rafal Turnips and Swede (my own fault) are too abstract.