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

## Hiding Implementations

## Hiding and Swapping of Implementations

### Implementation Hiding (Located in PicoContainer Gems)

This is where the implementation of the component is hidden from other components using it. The instance cannot be cast back to the implementation. It only works if the type has an interface that it implements.

    pico = new DefaultPicoContainer(new ImplementationHiding());
    pico.addComponent(Apple.class, AppleImpl.class);
    Apple a1 = pico.getComponent(Apple.class);
    // cannot cast back to AppleImpl

    pico = new DefaultPicoContainer();
    pico.as(HIDE_IMPL).addComponent(Apple.class, AppleImpl.class);
    Apple a1 = pico.getComponent(Apple.class);
    // cannot cast back to AppleImpl

    pico = new PicoBuilder().withImplementationHiding().build();
    pico.addComponent(Apple.class, AppleImpl.class);
    Apple a1 = pico.getComponent(Apple.class);
    // cannot cast back to AppleImpl

    import static org.picocontainer.behaviors.Behaviors.implementationHiding;
    ...
    pico = new PicoBuilder().withBehaviors(implementationHiding()).build();
    pico.addComponent(Apple.class, AppleImpl.class);
    Apple a1 = pico.getComponent(Apple.class);
    // cannot cast back to AppleImpl

This behavior leverages Reflection's dynamic proxy capability.

There's another implementation hiding behavior in Pico Gems called AsmImplemenationHiding that leverages ASM to make 'more concrete' hidden implementations than is possible via reflection. It generates real classes using ASM

### Hot Swapping (Located in PicoContainer Gems)

This builds on the ASMImplementationHiding behavior above, but also allows the hot swapping of component implementations during use. It has implicit caching behavior too.

    DefaultPicoContainer pico = new DefaultPicoContainer(new HotSwapping());
    pico.addComponent(Map.class, HashMap.class);
    Map firstMap = pico.getComponent(Map.class);
    firstMap.put("foo", "bar");
    HotSwappable hs = (HotSwappable) pico.getComponentAdapter(Map.class);
    Object oldMap = hs.getSwappable().swap(new HashMap());
    Map secondMap = pico.getComponent(Map.class);
    secondMap.put("apple", "orange");

    // first map and second map are the same
    // 'foo' is not a key in the map, wereas 'apple' is