PicoContainer

# About

- What is PicoContainer?
- Introduction
- Javadoc
- Downloads
- News
- FAQ
- Project Goals
- Support

# Core Concepts

- Component Lifecycle
- Dependency Injection
- Scoped Containers

# Dependency Injection

- Constructor Injection
- Setter Injection
- Annotated Field Injection
- Annotated Method Injection
- Typed Field Injection
- Named Field Injection
- Method Injection
- Multiple Injection
- Composite Injection
- Factory Injection
- Reinjection
- Injection via Providers

# Configuration

- Disambiguation

# Modifying Component Behaviors

- Modifying Behaviors
- Caching and Singletons
- Hiding Implementations
- Thread Safety Behaviors
- AOP Style Interception

# Advanced Concepts

- Fluent Style
- Arrays, Collections and Maps
- Leveraging Parameter Names
- Building Containers
- Component Properties
- Component Configuration
- Monitoring Component Events

# PicoContainer's Architecture

- Design Patterns
- Inversion of Control
- Component Adapters
- Mock Objects
- Terminology
- Container Comparisons
- Transparency

# Container Choices

- DefaultPicoContainer
- CommandLinePicoContainer
- PropertiesPicoContainer
- SystemPropertiesPicoContainer
- TransientPicoContainer
- TieringPicoContainer

# Dependant & Related

- Web Frameworks
- Scripting Support
- Persistence
- Logging

# Anti-patterns

- Propagating Dependency
- Long Constructor Argument List
- Container Dependency
- Unit Tests Use Container
- Singleton

# Help Pages

- Ambiguous Injectable
- Unprocessed Properties

# History

- Inversion of Control History

# Project Info

- Project
- Team

# Hosted by

# Tools

## FAQ

### Why PicoContainer 2.0?

First EJB 3.0 then Google's Guice seemed to copy the ideas from PicoContainer. EJB 3.0 invented the annotated types of injection, but crazily ommitted the Constructor Injection support, and Guice too the annotation idea and went far to further sith it. Soon after Guice, even the Spring Framework team decided to do things the direct way with their 'JavaConfig' capability.

So PicoContainer 1.x was refactored (not rewritten) into PicoContainer 2.0. All the unit tests were kept, and excerise took hundreds of commits, but the team is pleased with the result. PicoContainer has moved into the JDK 5 era and introduced some more innovations.

### Can my component use multiple constructors?

Yes.

You can code multiple constructors for a component:

    class MyComp {

        private ThreadPool theThreadPool;

        public MyComp(ThreadPool threadpool) {
            theThreadPool = threadpool;
        }

        public MyComp() {
            theThreadPool = new DefaultThreadPool();
        }

        // other methods.

    }

### How does PicoContainer decide what constructor to use?

PicoContainer will instantiate a given component using the "greediest" satisfiable constructor. By greedy, we mean the constructor that takes the most parameters. By satisfiable, we mean constructors where all arguments can be satisfied by other registered components.

If you register a component with no satisfiable constructors, or two or more ambiguous "largest" constructors, a RuntimeException will be thrown when you ask for the component instance.

We recommend for most components, you use only one constructor, although this is by no means a requirement.

### How does PicoContainer compare to EJB containers?

PicoContainer is rather different. EJB traditionally has loads of things you must extend, implement, provide and throw. EJB itself is also not an Inversion of Control (IoC) design. It is close in that components are managed by a container, but the cumbersome and static nature of the JNDI lookups ensure that it is not actually IoC. PicoContainer is not a superset of EJB though, as it provides no remoting capability out of the box.

### How does PicoContainer decide what constructor to use?

PicoContainer will instantiate a given component using the "greediest" satisfiable constructor. By greedy, we mean the constructor that takes the most parameters. By satisfiable, we mean constructors where all arguments can be satisfied by other registered components.

If you register a component with no satisfiable constructors, or two or more ambiguous "largest" constructors, a RuntimeException will be thrown when you ask for the component instance.

We recommend, for the sake of predictablility, that PicoContainer compatible components use only one constructor, although this is by no means a requirement.

### How to use primitive types in constructors?

PicoContainer will look for the greediest constructor of your component. But if your component's constructor depends on primitive types you may set the values explicitly.

    public interface ThreadPool {
    	void setSize(int);
    }

    public class MyComp {
    	private ThreadPool threadPool;
    	public MyComp(ThreadPool pool, int size) {
    		threadPool = pool;
    		threadPool.setSize(size);
    	}
    }

In this case you can set the parameters at registration time:

    DefaultPicoContainer pico = new DefaultPicoContainer();
    pico.addComponent(ThreadPool.class, DefaultThreadPool.class);
    pico.addComponent(MyComp.class, MyComp.class, new Parameters[] {
    	new ComponentParameter(),
    	new ConstantParameter(new Integer(5));
    })
    MyComp myComp = (MyComp)pico.getInstance(MyComp.class);

Use ConstantParameter to set constant values and the ComponentParameter to let Pico resolve the dependency.

### When should I use PicoContainer?

We recommend using PicoContainer when your application consists of many different components that are related to each other. Instantiating a lot of objects and lacing/connecting them in the right order can be difficult task.

### Why Another IoC Framework?

After a long period of watching or participating in the development of Apache's Avalon framework, we formed a team to start what we believed to be a far simpler IoC design. One that considered the component contract more important that the container.

When we set out to do this in 2003, there was nothing equivalent to PicoContainer (xContainer originally). XWork, that underpinned WebWork2 was a general/embeddable Setter Dependency Injection framework, but not well known. The Spring Framework started in the same timescale, and we were talking to its authors before Martin Fowlers Dependency Injection article. Later we discovered that Apache's HiveMind also was in the same space.

### Why Constructor Injection?

Constructor Injection is hard to swallow for developers who have been living with Interface Lookup (the Avalon or OSGi way) or Setter Injection for long. We think it's like TDD. Once you get the grasp of it, you don't go back. Here are some benefits of Constructor Injection:

- Constructor Injection makes a stronger dependency contract
- It is more succinct in terms of lines of code
- It is more succinct in terms dependency-statement-mechanism i.e. no XML, attributes, enabler interfaces etc
- A component that is Interface/Implmenetation separated should have the interface be the contract offered to other components, and the implementation potentially having some extra methods that are nothing to do with the contract.
- No indeterminate state. For setter injection and alike, not all the post instantiation setters may be called. Consider the non-container case for comp usage, if v1.2 of that comp introduces a new dependancy, with Constructor Injection the compiler will tell you.

### Will we support Guice's @Inject annotation transparently?

We could compile PicoContainer against Guice.jar and leverage the @Inject method with a new InjectionFactory (and probably will). The problem is that there is no easy way to use an annotation without having its class in the classpath. There's no easy 'transparent' solution for this.

Things fail silently if the jar is missing, unless the annotation is used - then it fails noisily. Meaning, the mere declaration of an annotation on a component is not enough to cause a ClassNotFoundException on load, if its not used:

    @Retention(RetentionPolicy.RUNTIME)
    @Target(value={ElementType.METHOD})
    public static @interface Bar {
    }

    ...

    import com.google.inject.Inject;
    public class Foo {

        @Inject
        @Bar
        public void setFoo(String str) {
            System.out.println("setFoo:" + str);
        }

        public static void main(String[] args) throws NoSuchMethodException {

            Foo foo = new Foo();
            foo.setFoo("hello");

            Method m = Foo.class.getMethod("setFoo", String.class);

            Annotation[] anns =  m.getDeclaredAnnotations();
            System.out.println("Num annotations: " + anns.length);
            for (int i = 0; i < anns.length; i++) {
                Annotation ann = anns[i];
                System.out.println("Annotation: " + ann.toString());
            }

            Annotation ann =  m.getAnnotation(Inject.class);
            System.out.println("InjectAnnotation: " + ann);
        }
    }

Leaving Guice out of the classpath, and trying to launch Foo like so:

    commandline: java -cp classes Foo
    setFoo:>hello
    Num annotations: 1
    Annotation: @Foo$Bar()
    Exception in thread "main" java.lang.NoClassDefFoundError: com/google/inject/Inject
            at Foo.main(Foo.java:32)

The class loads, but the @Inject annotation is not present in the set of declared annotations, but another in the classpath is. Lastly when accessed explicitly, there is an exception thrown. Contrast to, the same run with Guice in the classpath:

    setFoo:hello
    Num annotations: 2
    Annotation: @org.picocontainer.annotations.Inject()
    Annotation: @Foo$Bar()
    InjectAnnotation: @org.picocontainer.annotations.Inject()