Print
Container

NanoContainer Overview

NanoContainer is a script-enabled layer which builds PicoContainers. Trees of containers and components can be composed using several scripting languages:

Why multiple script language support?

Multiple script languages are supported because we officially stand against a single meta-data language. Of the script languages, XML is the most widely used and mature, but Groovy is most promising because of the its optional builder syntax.

Uses of NanoContainer

NanoContainer is primarily intended to be embedded inside other applications and frameworks. We recommend using NanoContainer when your application consists of many different components that are related to each other but you need composition driven by external scripts.

Embedded Example

// Instantiate the reader. It should point to a script.
FileReader script = ...;
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

// build the container from the script. GroovyContainerBuilder is used in this example
// but the appropriate ScriptedContainerBuilder should be used depending on the script type being read.
ScriptedContainerBuilder builder = new GroovyContainerBuilder(script, classLoader, parent, scope)
PicoContainer parentContainer = new DefaultPicoContainer(classLoader);

// create the container reference and pass them to the builder
ObjectReference containerRef = new SimpleReference();
ObjectReference parentContainerRef = new SimpleReference();
parentContainerRef.set(parentContainer);
builder.buildContainer(containerRef, parentContainerRef, scope, true);
PicoContainer picoContainer = (PicoContainer) containerRef.get();

Interpreted script languages

NanoContainer currently supports 4 different interpreted languages for container composition. The contract for Groovy, Beanshell, Javascript and Jython scripts is defined as follows:

  • The scripts have to define a "pico" variable of type MutablePicoContainer.
  • The script has access to a variable named "parent", which is a MutablePicoContainer instance or null. It should be used when constructing the "pico" MutablePicoContainer.
  • The script has access to a variable named "assemblyScope" that may be used in order to decide how to compose the container. The value of this variable can be any kind of object.

Groovy

pico = new org.picocontainer.defaults.DefaultPicoContainer(parent)
pico.registerComponentImplementation(org.nanocontainer.testmodel.DefaultWebServerConfig)
pico.registerComponentImplementation(org.nanocontainer.testmodel.WebServerImpl)

or

// GroovyNodeBuilder is the default Groovy builder and it is optional to specify it
// Specialised builder can be set - eg subclasses of GroovyNodeBuilder
builder = new org.nanocontainer.aop.dynaop.DynaopGroovyNodeBuilder()
pico = builder.container(parent:parent) {
    component(class:org.nanocontainer.testmodel.DefaultWebServerConfig)
    component(class:org.nanocontainer.testmodel.WebServerImpl)
}

Beanshell

pico = new org.picocontainer.defaults.DefaultPicoContainer(parent);
pico.registerComponentImplementation(org.nanocontainer.testmodel.DefaultWebServerConfig);
pico.registerComponentImplementation(org.nanocontainer.testmodel.WebServerImpl);

Javascript

(org.picocontainer.* and org.picocontainer.defaults.* imported by default)

var pico = new DefaultPicoContainer(new ImplementationHidingComponentAdapterFactory(), parent)
pico.registerComponentImplementation(Packages.org.nanocontainer.testmodel.DefaultWebServerConfig)
pico.registerComponentImplementation(Packages.org.nanocontainer.testmodel.WebServerImpl)

Jython

(org.picocontainer.* and org.picocontainer.defaults.* imported by default)

from org.nanocontainer.testmodel import *
pico = DefaultPicoContainer(parent)
pico.registerComponentImplementation(WebServerImpl)
pico.registerComponentImplementation(DefaultWebServerConfig)

XML

The above interpreted language scripts can equally be expressed in XML

<container>
    <component-implementation class='org.nanocontainer.testmodel.DefaultWebServerConfig'/>
    <component-implementation class='org.nanocontainer.testmodel.WebServerImpl'/>
</container>

The DTD details the full XML syntax.

Further reading

NanoWar

Powered by Atlassian Confluence