A thing to keep in mind is dependency injection != service discovery. 
 Dependency injection = an object knows what it needs but doesn't want to 
be responsible for making it.  Service discovery = an object doesn't know 
what it needs and may not have been compiled with everything it needs.

Does the thing creating the database know about the things that want to add 
configuration?  Or is it something where the thing that sets up the 
database is a sort of framework, and it needs to do some sort of lookup to 
find the things that want to contribute?

If the thing that creates the database *does* know about the things that 
would add configuration, then the decoupling you're trying to achieve is 
actually an illusion, so just initialize them all and pass them in and 
don't worry about it.

If on the other hand, the framework piece doesn't know about it, then you 
have a service discovery problem - you need a way to look things up.

I've used two different patterns for that with Guice.  The first is 
actually not Guice related - it's using the JDK's ServiceLoader (in this 
case, via NetBeans Lookup api, which has a handy @ServiceProvider 
annotation for registering services ServiceLoader can see).  Here's an 
example - in this case I'm binding Jackson's ObjectMapper for JSON 
processing, and I want anything on the classpath that wants to configure 
JSON serialization to have a chance to:
https://github.com/timboudreau/giulius-web/blob/master/jackson/src/main/java/com/mastfrog/jackson/JacksonModule.java

An alternative way that is more Guice-y, but which I like less for reasons 
I'll detail is where you have a "Registry" singleton, which objects can 
register themselves with;  then you bind the things that should contribute 
some configuration as eager singletons, so that when you ask the contents 
of the registry, you get everything that was bound that way.  Here's an 
example of that - in this case, I want to register things that intercept 
the creation of MongoDB databases and collections (in case they want to 
create indexes or set up some default contents):
https://github.com/timboudreau/acteur/blob/master/acteur-mongo/src/main/java/com/mastfrog/acteur/mongo/MongoInitializer.java

The pros of the latter approach is that you can turn things off by 
unbinding them (as opposed to changing the classpath or recompiling the 
contributor - although Lookup actually has a way of declaratively removing 
services).  The cons are that objects which are to be subclassed but 
register themselves in some registry in their superclass constructor is an 
antipattern - you can end up with weird race conditions where other threads 
are banging on your object's methods before its constructor has completed 
(you could eliminate the register call in the super constructor, but you'd 
have to tell subclassers "BTW, if you don't do this incantation your code 
will mysteriously not work", and inevitably someone will have exactly that 
problem - not cool).

Hmm, it now occurs to me that there's probably some clever interception 
thing I could have done instead of that registry...nonetheless...

-Tim

-- 
You received this message because you are subscribed to the Google Groups 
"google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to