The code attached extracts the concern of component registration out into an interface - "ComponentRegistrar":
public interface ComponentRegistrar
{
public void registerComponent(Class type, Class impl);
public ComponentSpecification []getRegistered();
public void addParameterToComponent(Class componentImpl,
Class parameter,
Object arg);
public List getParametersForComponent(Class componentImpl);
}
So its now possible to chain ComponentRegistrar impls to add
behaviour to component registration. Example: provide a logging instance to constructors without having to worry about logging in configuration files etc. Can be done like this:
final InputSourceComponentRegistrar registrar =
new InputSourceComponentRegistrarImpl(
new StringBasedComponentRegistrarImpl(
new LogEnablingComponentRegistrar(
new DefaultComponentRegistrarImpl())
));
final ExperimentalPicoContainer container =
new ExperimentalPicoContainer(
new DefaultComponentFactory(),registrar);
registrar.registerComponents(new InputSource(
new StringReader(xml)));
LogEnablingComponentRegistrar does this:
public void registerComponent(Class type, Class impl) {
final Class firstParameterType =
impl.getConstructors()[0].getParameterTypes()[0];
if (firstParameterType == Log.class)
{
addParameterToComponent(type,Log.class,
new LogImpl(impl));
}
delegate.registerComponent(type,impl);
}
So this allows me to configure this component:
public LoggableMockComponentImpl(Log log, int port)
{
this.log = log;
this.port = port;
}
with this XML:
"<components>" +
" <component class=\"LoggableMockComponentImpl\">" +
" <param type=\"java.lang.Integer\">12345</param>" +
" </component>" +
"</components>";.
There is no mention of logging, since the logging dependency is handled centrally by the decorator.
ExperimentalPicoContainer is copy of HierarchicalPicoContainer but with all the registration stuff delegated to a ComponentRegistrar instance.
Few things about this:
- It means we can insert all the check methods (like checkConcrete() etc) into the decorator chain instead of hard coding them into a default impl, if we want to. Additionally, PicoContainer implementers now have a means of inserting their own check methods that we didn't think of.
- It keeps ExperimentalPicoContainer small and focussed (I did not clean it up as much as possible in the attached code).
- If the number of potential instances of ComponentRegistrar is considered too large, we can provide classes that bundle them into sensible "families".
Aslak,
I opened Pico-16 just before you to deal with this very issue I will close 16 and move comments to this one.