PicoContainer “as()”
Did 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.
June 30th, 2003 at 5:08 pm
//Calls peel() on all Peelable components in the container
in which order container calls the peelables? is there a way to specify that. because there might be dependency only on peelables that one should be called before the other.
thanks..
June 30th, 2003 at 7:20 pm
The order will be either in the order of instantiation or the reverse order. For lifecycle management you’d probably want to call in the instantiation order for starting them, or the reverse order for destroying. You specify this with a boolean when you ask for the proxy.
Chris and my stuff has been refactored a little bit. You can have a look at its usage in the following test case:
http://www.picocontainer.org/xref-test/picocontainer/hierarchical/ClassicLifecycleTestCase.html
and
http://www.picocontainer.org/xref-test/picocontainer/defaults/DefaultPicoContainerTestCase.html
The as() method is now called picocontainer.defaults.DefaultPicocontainer.getAggregateComponentProxy()