With the invaluable help of Bruno Harbulot (and Thierry and Jerome!), I checked in a preliminary version of org.restlet.ext.guice to the incubator sources. I confirmed that it works for one somewhat artificial example (see org.restlet.ext.guice.example), but it needs more eyes on it, it needs tests, and it needs some real use.
The design is very much like what I reported blogging about at the beginning of this thread, except that FinderFactory is now called DependencyInjection because it adds a few "extension methods" for attach/attachDefault (on Routers and Virtual Hosts) and setNext (on Filters, Servers, and ServerLists). The idea is that you "wrap" regular attach/attachDefault/setNext calls with DependencyInjection calls to inject a target ServerResource. For example: DependencyInjection di = ...; TemplateRoute route = di.attach(router, "/path", MyResource.class); // same as router.attach("/path", di.finderFor(MyResource.class)); // Secret is a Qualifier (JSR-330's version of BindingAnnotation) di.setNext(filter, AnotherResource.class, Secret.class); // same as filter.setNext(di.finderFor(AnotherResource.class, Secret.class)); I moved the FinderFactoryModule into the RestletGuice class, which was previously just a container for static methods, so it is now RestletGuice.Module. It implements DependencyInjection, and it still has the property that if it hasn't been used to create an Injector by the time one of its DependencyInjection methods is called, an Injector is created lazily from it. I removed all mention of com.google.inject from DependencyInjection, so this interface would be suitable for use with any JSR-330-compliant DI framework. All this meant was replacing methods that take a Key argument with variants taking a Class<? extends ServerResource> and a Class<? extends Annotation>, where the latter must be a javax.inject.Qualifier (or com.google.inject.BindingAnnotation). I removed support for Restlet 1.1 Handlers. I don't think I'm using any features of Guice introduced in 2.0, but I haven't checked to see if it still works with Guice 1.x. I haven't touched the code that I put in originally to deal with use of a single instance of a RestletGuice.Module by multiple Injectors; I suspect it isn't correct. I'll fix it eventually, but it seems like a pretty marginal use, so it's not a big priority. I haven't provided any custom Scopes because no one has told me of a Scope need that is so common and yet so tricky that it's worth complicating this extension to keep people from having to roll it themselves. If you think you have such a need, let me know. ResletGuice.Module binds providers for Application, Context, Request, and Response that by default use the getCurrent class method of the corresponding class. The getCurrent methods rely on a ThreadLocal value that is set properly for most purposes, including tasks executed via a TaskService; if you need to change the default behavior, you can override newApplicationProvider, newContextProvider, newRequestProvider, and newResponseProvider in a subclass of RestletGuice.Module. There should be no barriers to using RestletGuice.Module in conjunction with other frameworks, including guice-servlet. All you need to do is ensure that your resource bindings are made in Modules passed to the constructor of a RestletGuice.Module that is used to create the final Injector. I was going to extend Router to make the functionality a little more transparent, but that would prevent the extension of Router for other purposes. Also, for completeness I would have had to extend VirtualHost, Filter, Server, and ServerList, and you'd have to use those new subclass names to get access to the variant that takes a qualifier annotation type. It would have been a lot of API noise instead of just one interface. I considered another approach that I'd like to get feedback on, a mini-DSL, where the previous examples would look like this: TemplateRoute route = di.with(router).attach("/path", MyResource.class); di.with(filter).setNext(AnotherResource.class, Secret.class); That would add a few more interfaces for the intermediate types in the DSL, but they wouldn't be in your face. Would this be a better API? --tim ------------------------------------------------------ http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2427214