Stephen McConnell wrote:
If this is the case, I just make a ContextService, that gives me the objects I want. Your explanation fails to make me understand the difference between a Service and a Context.Nicola Ken Barozzi wrote:Leo Sutic wrote:Stephen,
your point is taken that all operations that are not a lookup of a
constant value based on a key (such as getHomeDirectory)
can be seen as a peer service.
First, everything can be seen as a peer service. We don't really
need the Configurable interface. Instead, one could lookup a
configurator service:
interface Configurator {
Configuration getConfiguration ();
}
and use the returned Configuration. The container would ensure you
got the correct config.
However, while it reduces the set of classes one has to deal with
("everything is a service") there are practical issues with this.
Peter D. mentioned a few of them here:
http://marc.theaimsgroup.com/?l=avalon-dev&m=103809692826408&w=2
and I believe he's right.
My analysis would be that the real problem *is* the Context interface.
Specifically, that it is a total mess. What is it for? Constant value lookup?
Container specific services only? Container provided services in general?
If anything, this is something that has to be solved before we go on.
Yes, I feel the same way.
The Context is something that has been used in the past and is used now in many ways, like a sort of catchall thing.
"Hey, where do we put this? Use the Context".
Q: I have a logger - how do I assign it to the object?
A: You use LogEnabled
Q: I have this static configuration fragment - how do I get this to the object?
A: You use Configurable
Q: I have a set of static parameters - how do I pass them to the object?
A: You use Parameterizable
Q: I have a logger - how do I assign it to the object?
A: You use LogEnabled
Q: I have a service - how do I suply this to the object?
A (a) In ECM/Fortress you lookup the service by passing in the service interface name
A:(b) In Merlin/Phoenix you declare a named dependency with you component and ask for it using lookup
Q: I have some data that I want to supply to my object - how do I do that
A (a) You use the Context interface
A (b) In your using Fortress or Merlin you can also apply the data to the component using an lifecycle extension
I don't mean that "Context is for many a happy ComponentManager" is a good thing. It makes us use as Services things that in fact are Objects, without any proper decalarations and dependency resolution.I even wonder why we have a Context interface at all, since we are casting as we do with Services (and there we have removed the Component Interface). Context is for many a happy ComponentManager.Thats a very ECM mindset - ECM notion of service is not based on depedencies or the fact that a component explicity declares the servicees it provides. In ECM you have a lookup mechaism and some mcahanics that handle things based on marker interfaces. If you want to incorporate static service management into ECM you would discover that there are differences between a service and java,.lang.Object - most notable is a version, supplimenting this are attributes. Service != Object.
Now, in real life, what is a Context for?
Let me try to make a simple example.
Let's say that I make my famous GooServer using Avalon. It's an HTTP server, and it sends every single request to a chain of Goolets, that are Avalon Components. The Server itself is a simple GooContainer.
,------------GooContainer---------------------.
| |
| | |
| /-----GooLet1-------\ | ---------- |
GooRequest | | | |-| | |
------->------------ goo(GooRequest) | | | Storage| |
| | |---| | Service| |
| ------ GooResponse | | | | |
| | | | | ---------- |
| | \-------------------/ | |
| | | ---------- |
| V |-| | |
| | | | Search | |
| | /-----GooLet2-------\ | | Service| |
| | | | | | | |
| ------ goo(GooRequest) | | ---------- |
GooResponse | | |---| |
-------<------------ GooResponse | | ---------- |
| | | |-| | |
| \-------------------/ | |Template| |
| | |Service | |
| | | | |
| | ---------- |
| |
,----------------------------------------------.
When a GooRequest arives, the simple GooContainer intantiates the Goolets that its Configuration specify, runs through the initial lifecycle Interfaces (giving them also itself as a reference), and calls the
GooResponse goo(GooRequest)
on them one after the other.
Each GooLet can be Composable, thus have a reference to Services that are provided. As you see, there is no Context (yet).
Imagine though that you have 3, 4, 5 requests, and concurrent requests. Each Service is the same object as before, thus *is not scoped per chain invocation*.
Now the GooLet2 wants to tell Goolet1 something. It can only via the GooResponse-GooRequest, because it's the only object in the above scenario that is per-request.
Hmmm, no Context yet...
NOw I want to track sessions between invocations.
Services are always the same.
Requests are atomic... I need a Context. Something that gives me information sharing per session.Ummm, something like a request context ?
Now, what is a Context?
If it's a bag to put values common to all Goolets, it's a Service.
If it's to be shared by all Goolets in the same invocation it's a Request.
So it seems to be a bag to hold info between invocations but pertaining to a certain criteria (session for example).
You describing the notion of a *request* context as opposed to something like a * GooLet* context.
In both cases the the context object is an instrument that can be populated with data and safely supplied to a consumer.
I would disagree with the conclusion about most cases. Given the framework contracts, there are many occasions where you want to pass a set of runtime parameters to an object, for example, I may want to pass a classloader, a date, and a public key chain. The configuration interface is clearly inappropriate as is the parameters interface, service interface is inappropriate these objects do not publish service interfaces - they are what they are - data that collectively define a context.
So
X requests for X invocations
N services for X invocations
Y contexts for X invocations
Where
Y<=X
N not related to X || Y
This is not how Context is used now in most cases. It's used to get a directory for example, which in this case seems to be a Service... so?
>
A context instance is a readonly bag of tagged data.Please expand on this. Especially on the "publis service interfaces" part and the "readonly bag of tagged data".
I have the strange feeling that the Context described here is a ContainerRuntimeDataService.
Data can can be transformed into objects capable of providing behaviour by narrowing the data to some behavioural interface (such as a key-chain). In such a case you are no longer dealing with the context object, your dealing with a functional object - i.e. its a seperate concern.
This is true in the scenario you describing above, its true in terms of the usage I apply context to, and its is totally consitent with the framework defintion.
So, where does this take us?
Cheer, Steve.
--
Nicola Ken Barozzi [EMAIL PROTECTED]
- verba volant, scripta manent -
(discussions get forgotten, just code remains)
---------------------------------------------------------------------
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
