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

## Propagating Dependency

## Symptoms

A dependency exists solely to be propagated to another class, but no methods are called upon the dependent object itself. For example:

    public class AControllerImpl implements AController {

        private SomeService service;
        private int someId;

        public AControllerImpl(SomeService service) {
            this.service = service;
            this.someId = generateRandomNumber();
        }

        public launchAnotherController() {
            AnotherController anotherController = new AnotherControllerImpl(service, fooId);
            anotherController.launch();
        }

        // ...
    }

In this example, no method-calls are made upon 'service', it is simply propagated to the constructor of 'AnotherControllerImpl'. Therefore, it is not a valid dependency for 'AControllerImpl'.

## Causes

DependencyInjection has been partially applied to a hierarchy of classes. This could be because some classes in the hierarchy depend upon instance state not available at container-registration time.

## What To Do

Apply DependencyInjection to 'AControllerImpl' by replacing the dependency on 'SomeService' with a dependency on 'AnotherController'. If, as in the example above, 'AnotherControllerImpl' has a dependency upon some state that is not available at container-registration time, then we need to introduce a factory for creating 'AnotherController' as follows:

TODO: This is maybe a little contrieved for this example. Maybe remove or simplify. (AH).

    public class AControllerImpl implements AController {

        private AnotherControllerFactory anotherControllerFactory;
        private int someId;

        public AControllerImpl(AnotherControllerFactory anotherControllerFactory) {
            this.anotherControllerFactory = anotherControllerFactory;
            this.someId = generateRandomNumber();
        }

        public launchAnotherController() {
            AnotherController anotherController = anotherControllerFactory.createAnotherController(someId);
            anotherController.launch();
        }

        // ...
    }

'AnotherControllerFactory' is an interface:

    public interface AnotherControllerFactory {
        AnotherController createAnotherController(int someId);
    }

It can be implemented as follows::

    public class AnotherControllerFactoryImpl implements AnotherControllerFactory {
        private SomeService service;

        public AnotherControllerFactoryImpl(SomeService service) {
            this.service = service;
        }

        public AnotherController createAnotherController(int someId) {
            return new AnotherControllerImpl(service, someId);
        }
    }

Now we can register both 'AControllerImpl' and 'AnotherControllerFactoryImpl' in the container. When 'AControllerImpl' is instantiated, it is supplied with an implementation of 'AnotherControlFactory' that it can use to create an 'AnotherController' instance.

# Exceptions

When [Migrating from executors to services], it can sometimes be difficult to avoid introducing a Propagating Dependency. In these cases, the Propogating Dependency can be considered as a good first step towards PicoFication of a set of classes. An effort should be made to complete PicoFication at some stage by making a series of further steps as described above.