|
|||||
|
|||||
User DocumentationOne minute descriptionTwo minute tutorial Five minute introduction Advanced Topics FAQ Container Components Terminology Mock Objects Inversion of Control Types PatternsInversion of ControlDependency Injection Constructor Injection Setter Injection Interface Implementation Separation Lifecycle Antipatterns Developer DocumentationHow To Contribute Relative Volunteering Release Process Project InformationSloganMailing lists Source Repositories Open Issues Blog entries Statistics Team Sister Projects TShirts MiscellaneousDifferentiatorsNirvana Full SitemapFeeds
|
SymptomsClasses that depend on the container. Consider the following example. We have a class BImpl that requires an A instance. It declares the dependency on the container so it can look up that A:
public interface A { } public class AImpl implements A { } public class BImpl implements B { private final A a; BImpl(PicoContainer pico) { a = (A) pico.getComponentInstanceOfType(A.class); /* alternatively: a = (A) pico.getComponentInstance("a"); */ } } It can be used in the following way:
MutablePicoContainer pico = new DefaultPicoContainer(); pico.registerComponentImplementation("a", AImpl.class); pico.registerComponentImplementation("b", BImpl.class); ... B b = (B) pico.getComponentInstance("b"); This will work, but it's an antipattern. (The PicoContainer instance is implicitly available as a "hidden" component adapter. However, it is highly discouraged to have regular components depend on PicoContainer. The only reason why it is available implicitly is to be able to register containers inside other containers - as this is how child containers will get the reference to their parent). The reasons why the above implementation of BImpl is an antipattern are:
CausesNot sure. Poor understanding of how PicoContainer works? Not being able to think "simple"? What to doThe simple and elegant solution to this antipattern is not to complicate the world more than it is. Here is how it should be: public class BImpl implements B { private final A a; BImpl(A a) { this.a = a; } } PicoContainer will figure out that BImpl needs an A instance, and will pass in the AImpl, as this is an implementation of A. |
||||
|