Symptoms

Classes 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;

    public BImpl(PicoContainer pico) {
        a = (A) pico.getComponentOfType(A.class);
        
        /*
        alternatively:
        a = (A) pico.getComponent("a");
        */
    }
}

The usage would probably look similar to:

MutablePicoContainer pico = new DefaultPicoContainer();
pico.addComponent("a", AImpl.class);
pico.addComponent("b", BImpl.class);
pico.addComponent(pico);

...
B b = (B) pico.getComponent("b");

It will work, but it is an antipattern.

The reasons why the above implementation of BImpl is an antipattern are:

Causes

What to do

The 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.

The One Major Exception

When you go to integrate all your components into a single application, SOMETHING is going to have to wire all these components together. In Pico-land, we call that the "bootstrap" script. (Script, is a loose term, it could easily be a reference to PicoContainer inside a class' main() function.) The pattern of this code will often look like this:

public class Bootstrap {
	
   private PicoContainer pico = new PicoBuilder().withLifecycle().withCaching().build();


	public static void main(String[] args) {
		Bootstrap bootstrap = new BootStap();
		bootstrap.start();
	}


	public void start() {
		/*  pico.addComponent(A.class), pico.addComponent(B.class) */
		/*  etc. */

		
		pico.start();
		//enter some sort of event loop.


		//Event loop broken.

  		pico.stop(); 
 	}


	public void stop() {
		pico.stop();
		pico.dispose();
	}
}

PicoContainer has a sample project called "bootstrap" that does just this sort of thing. For web applications, Pico uses a WebappContextListener to bootstrap an application-level container, and a Servlet filter to bootstrap a request-level container.