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

## Reinjection

Reinjection is where an existing instance, that may have been already created by PicoContainer, can have a method called to inject more dependancies.

## Direct Reinjection via 'Reinjector'

Consider the following example of class that could benefit from reinjection:

    public class ShoppingCart {
      private Store store;
      private User user;
      public ShoppingCart(Store store, User user) {
        this.store = store;
        this.user = user;
      }
      public boolean addItemTo(Make make, Model model, int quantity) {
    	Cart cart = store.getCart(user);
    	if (cart.contains(make, model)) {
    		cart.for(make, model).increaseQuantity(quantity);
    	} else {
    		cart.addItem(make, model, quantity);
    	}
    	return true;
      }
    }

The class would be instantiated and have 'store' and 'user' satisfied via constructor injection. Later, perhaps corresponding to a web request, addItemTo could be invoked with relevant parameters. Indeed the addItemTo method could be called many times after instantiation.

And here is a fragment of Java showing reinjection in use:

    addItemMethod = ShoppingCart.class.getMethods()[0]; // a poor way to select a method!
    reinjector = new Reinjector(picoContainer);
    boolean result = (Boolean) reinjector.reinject(ShoppingCart.class, addItemMethod);

In the above example, the PicoContainer instance (or one of its parents) can inject a Make, a Model and a quantity (int / Integer).

For reinjection to work, you really need to know the exact method to be injected into. You indicate which method by a reflection method reference (as in the example above), or by method name ("addItemTo" should be unique in the class). You could also rely on an @Inject annotation, but that only makes sense where there is one method in the class to be used in this way. If you are implicating a reinjection method by name (rather than reflection method reference), and there are more than one matching, then the last one invoked will have it's return value returned to the caller.

## Reinjection as a type of regular Injection

This is where reinjection is managed by a PicoContainer instance, rather than directly.

    public class ShoppingCart {
      List list = new ArrayList
        ();
            public void addItemTo(Make make, Model model, int quantity) {
            list.add(new Item(make, model, quantity));
            }
            }
            ...
            addItemMethod = ShoppingCart.class.getMethods()[0]
            pico = new TransientPicoContainer(new Reinjection(new MethodInjection(addItemMethod), parent), parent);
            cart = pico.getComponent(ShoppingCart.class);

The method addItemTo() is called during the getComponent() invocation. This works because the return type is void. A non-void type would cause getComponent() to fail with a class cast exception. If you have that component design need, you need to use the Reinjector directly.