Authors: paul
Overview
Configuration for PicoContainer components requires some explanation. The basic idea is that a component should not be tied to a single configuration design.
There are two ways a developer may declare configuration needs for a component. The first is as seperate parameters in the constructor, the second is as a bespoke configuration pseudo-component, also passed in through constructor.
Constructor parameters
Consider a component a that requires configuration :
class Foo {
public Foo(DependantComp dComp, String fooName, Integer barNumber) {
}
}
Clearly the string and the integer are not components. What we need is a way of passing in those parameters at runtime. Possibily interleaved with real components.
MutablePicoContainer pico = new DefaultPicoContainer(); pico.registerComponentImplementation(DefaultDependantComp.class); pico.registerComponentImplementation(Foo.class, new Parameter[]{...});
We're trying to illustrate the intermingling of components and configuration. Well perhaps we are if you consider the following component :
class Foo {
public Foo(Wilma wilma, String fooName, FredImpl fred, Integer barNumber) {
}
}
....
MutablePicoContainer pico = new DefaultPicoContainer();
pico.registerComponentImplementation(Foo.class, new Parameter[]{...});
pico.registerComponentImplementation(Wilma.class, WilmaImpl.class);
pico.registerComponentImplementation(FredImpl.class);
Pseudo-component
class Foo {
public Foo(DependantComp dComp, FooConfig fooConfig) {
}
}
interface FooConfig {
String getFooName();
int getBarNumber(); // note this is int not Integer (restriction lifted).
}
Without going into the how, many implementations of the FooConfig are possible.
MutablePicoContainer pico = new DefaultPicoContainer();
pico.registerComponentImplementation(DefaultDependantComp.class);
pico.registerComponentImplementation(Foo.class);
pico.registerComponentImplementation(DefaultFooConfig.class);
Clearly a person needs to write an adaptor, but any adaptor can be written. The developer who uses the component can do anything - they are not forced to fit one configuration design.
Anti-patterns
In non IoC designs, a component may hard code its configuration in one of a number of ways.
True hard coding:
class MyWebServer {
ServerSocket socket;
public MyWebServer() {
}
public void start() {
// listen on port 80
socker = new ServerSocket(80);
}
}
Bound to a specific properties file:
class MyWebServer {
ServerSocket socket;
public MyWebServer() {
}
public void start() {
ResourceBundle rb = new ResourceBundle("MyWebServer.properties");
socker = new ServerSocket(rb.getIntProperty("port.number");
}
}
There are IoC anti-patterns as the embedor can't choose their own configuration mechanism. An application comprising a number of components may have to include multiple xml and properties files to control the configuration.
