PicoContainer “as()”
Monday, June 30th, 2003Did my first commit on picocontainer on the weekend after lurking for too long — only to find out that Aslak and I had the same idea - there is code in nano to do almost exactly the same thing.
[You can also read the original mail thread]
Say I have an interface:
==
public interface Peelable {
void peel();
}
I want to be able to call peel() on all components in a container
that implement Peelable. Conceptually (at least the way I think about
it), this is like calling peel() on the container itself.
So what if I could dynamically make the container implement any
arbitrary interface:
pico = new MorphingHierarchicalPicoContainer(...); pico.registerComponent(PeelableComponent.class); pico.registerComponent(AnotherPeelableComponent.class); pico.registerComponent(YetAnotherPeelableComponent.class); pico.start(); //Get a proxy for the container that implements Peelable Peelable asPeelable = (Peelable) pico.as(Peelable.class); //Calls peel() on all Peelable components in the container asPeelable.peel();
This is easy to implement using a dynamic proxy. The proxy just
iterates through the components and calls the interface methods on
each one in turn.
Some of the advantages of this are:
- Totally decoupled lifecycle methods are now possible, because I can
adapt *any* interface, and it is not coupled to Pico at all.
- many competing / complementary lifecycle patterns can be implemented
without comprimising pico’s simplicity
- the interface is decoupled from Pico, interface methods can throw
Exceptions that are domain specific. Again, pico doesn’t need to know.







