Currently we have several ways of looking up components and resolving them. We typically refer to them by the container that implements them, i.e. the ECM/Fortress way or the Phoenix/Merlin way. Each has their advantages and disadvantages. Hopefully we can look at them and come up with the best solution.
Issue #1: Component Lookup/Release ---------------------------------- Part of what the ComponentSelector solved was the need for lookup and release mechanisms. Simple types cannot provide release mechanisms, so only ThreadSafe components can be safely used with simple types. In the Phoenix realm, that is not a real problem as most services are ThreadSafe anyway. However, at lower levels (i.e. Avalon embedded in another container hierarchy like Servlets) developing all components as ThreadSafe is not always practical. We need transient components. Since the solution we come up with must work in the general case, the compromise was the ComponentSelector--something that Peter D. regrets to this day ;p. In the embedded Avalon world (ECM and friends), the ComponentSelector works very well because we can look up the components we need from the selector by names supplied in the configuration. It is a desparate need. We have recently decided that we want to move away from a Selector based approach--which would bring us back to Peter D.'s original solution which is the hierarchical ComponentManager. We still want to explore that approach, because it gets rid of the intermediate need of an additional lookup device (which includes Map/Array/ **Selector). In order to fully get away from the need of the *Selector interface, we need a way to mask the component management for transient components. One way is through dynamic proxies that will pull an instance from a pool as needed, and will automatically return it after a specified period of inactivity. The major issue is managing state information. In order to work with transient/stateful components we need a session mechanism so that a component can store its state in the session so the client will never be the wiser. BTW, for the benefit of all who weren't around the last time we had the many components for one role discussion, a Releasable interface was vetoed. I proposed adding a method like "release()" to the component interface that would provide real semantics for having a Component interface as well as not requiring release() on the CM/CS interfaces. I think I was the only one in favor of that at the time. Issue #2: Component Definition ------------------------------- In the ECM/Fortress world, things are simple. There is no meta info (for the time being) to write, no assembly files to write. That is because they take advantage of the interface names as a lookup key resolution policy. They dynamically determine how to respond to a lookup request. In the Phoenix/Merlin world, things are more complex, more powerful, and more static. As a result, ECM/Fortress can easily handle looking up components from a **Selector because the lookup keys are typically part of the configuration. That is a good thing IMO. The power of meta information comes at a price. Until support was added for the array/hash return types (substitutes for the **Selector), there was no real way to look at a collection of components and determine at assembly/deployment time which components you really wanted. The problem is that the array/hash return types really only work in the Phoenix arena because all the components are ThreadSafe--not transient. That said, I think the declaration of array/hash/selector in meta information can be better stated. At development time, we know how we want to lookup information, we just need to know the lookup value at runtime. To support this, I propose the following changes to the declaration and lookup of components: <dependencies> <dependency> <service name="org.apache.MyService" as="#"/> </dependency> </dependency> With this change, we declare that we want the lookup for the specified service to be a Map. In fact we can do better by using words: "array", "map", "selector". The container knows how to bind the required services from that point. In our code, we have this: void service( ServiceManager sm ) { Map services = (Map) sm.lookup( Service.ROLE ); // use them here. } At assembly time, we specify them like this: <block class="org.apache.MyComponent" name="myComp"> <provide name="service1" role="org.apache.MyService"/> <provide name="service2" role="org.apache.MyService"/> <provide name="service3" role="org.apache.MyService" alias="myAlias"/> </block> There is no need to repeat the as="#"/as="map" in the assembly, because we already know that the component is looking for multiple entries like that. This way we can leverage the power of meta-info with the flexibility that was desired. I would even go farther and say that we would be able to remove the necesity for the role="..." attribute in the assembly if the component only implements one role. -- "They that give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety." - Benjamin Franklin -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>