Services are loaded by the normal class loader without any special trickery. We create classes (proxies and such), but don't modify existing classes for Tapestry IoC. This is necessary to ensure that services code inter-operates properly with all kinds of third party, legacy and other code that is far, far beyond the scope of Tapestry IoC.
To encourage service implementations to properly store service depenencies as final instance variables, such dependencies are passed only into the constructor. So for services, injection is assumed, for the constructor parameters (as if an @Inject annotation was present). Now for components, it's a different story. The component classes are very specific to Tapestry, not intended for reuse elsewhere, and are modified at runtime to work properly and efficiently within the constraints of Tapestry's multi-threaded runtime environment. Tapestry components are quite a bit different from service, in terms of lifecycle, and in terms of the what can be injected (all sorts of resources besides services) and in the fact that they quite often have considerable (if largely temporary) internal state, while services most often have no internal state at all. Constructor injection is insufficient for components, because Tapestry needs to really know about the individual fields. For example, if you: @Inject private MyService _service; ... and then in some code: void onActionFromNotAGoodIdea() { _service = new MyOtherImpl(); } You'll actually get a runtime error explaining that the field is read only. So field injection is both necessary and requires far less typing ... you don't have to write a constructor and assigning all the fields from it. On the other hand, the fields aren't final (though they often act final). The real downside is that you have a similar concept, injection, with two very different expressions. It would be interesting if Tapestry IoC could support injection on fields, and "backtrack" from the field to the constructor parameter. It might also be interesting if components could define a constructor and Tapestry could work forwards from the parameter annotations forwards to the fields. I think both approaches would require a large amount of effort and may not actually add any value. Certainly in the short term, people would be much happier if we got the Ajax support going. Of course, I'm writing this on my PC while I get Leopard installed onto my Mac (my main development machine). On Nov 10, 2007 12:43 PM, Michael Courcy <[EMAIL PROTECTED]> wrote: > Hi > > Thanks again for this effort of documentation. > > I have a question about dependency injection between services. > > We can inject a service thanks to the @Inject annotation in a page > component. > I find this feature pretty handy. > > But (correct me if I'm wrong but I think I'm not because I test it) we > can't @Inject a service in a sercice. > Instead we must provide the service to the other service through its > constructor. > > Why did you make this choice ? > > I would find useful as well to inject a service in a service with the > same annotation ? > > Michael > > > Howard Lewis Ship a écrit : > > I've been working on new documentation about Tapestry IoC (similar > > stuff will be coming for Tapestry core): > > > > Overview: > > > > http://tapestry.formos.com/nightly/tapestry5/tapestry-ioc/overview.html > > > > Cookbook: > > > > http://tapestry.formos.com/nightly/tapestry5/tapestry-ioc/cookbook/index.html > > > > Feedback is encouraged! > > > > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > > -- Howard M. Lewis Ship Partner and Senior Architect at Feature50 Creator Apache Tapestry and Apache HiveMind --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]