I had a similar idea as Jesse when solving the problem of having
multiple EntityManagers bound to one Injector by using annotated
bindings. The requirements are
1. having multiple object graphs with slightly different bindings
(e.g. the EntityManagerFactory is different for each PerstenceUnit),
but
2. reuse the classes that have @Inject dependencies
3. bound them all to one Injector with different binding annotations.
This requirements were discussed on this mailing list several times
often using the term "robot-leg-problem". My idea was to create a
fully usable (Sub-)Injector for each PersistenceUnit by binding all
necessary types without any annotations. This ensures I can reuse my
types, providers, etc. without using any fancy logic to be able to
Inject annotated bindings (this solves point 2). I have introduced the
term SubInjector, because after creating all SubInjectors I create a
root Injector that is visible to the application by iterating over all
SubInjector's bindings and bind them to the root Injector using one
binding annotation for each SubInjector (solves point 3). This looks
like:
class SubInjector {
interface AnnotatedSubModule {
Module annotatedWith(Class<? extends Annotation>);
Module annotatedWith(Annotation);
}
static AnnotatedSubModule bind(Module...) {
// create injector from modules and
// return a module with annotated bindings
// to this injector.getBindings().getProvider()
}
}
with the concrete usage for binding different PerstenceUnits:
Injector applicationInjector = Guice.createInjector(
SubInjector.bind(JpaModule.createModuleForUnitName("crm"))
.annotatedWith(CustomerRelationManagement.class),
SubInjector.bind(JpaModule.createModuleForUnitName("business"))
.annotatedWith(BusinessTasks.class)
)
class JpaModule {
static Module createModuleForUnitName(final String unitName) {
return new AbstractModule() {
bind(EntityManagerFactory.class)
.toInstance(javax.persistence.Persistence
.createEntityManagerFactory(unitName));
bind(EntityManager.class).toProvider(new
Provider<EntityManager>() {
@Inject EntityManagerFactory factory;
public EntityManager get() {
return factory.createEntityManager();
}
}
});
}
}
class Application {
@Inject @CustomerRelationManagement EntityManager crmEntityManager;
@Inject @BusinessTasks EntityManager taskEntityManager;
}
Back to discussion: My current wish/problem is, I am not able to
reference bindings of the root Injector from the SubInjectors. I would
love to see the each Subinjector created as an child Injector of the
parent/root Injector, but the problem is that the parent Injector
actually has to be fully initialized before you can use it to create
child Injectors. Because I am creating modules for each child/sub
injector which are used to configure the parent/root injector
afterwards, I am not able to also use the parent injector as a place
of common bindings, that are available for each child injector (sounds
a bit like the chicken-or-egg question to me).
I know a can deal with this problem by simply using multiple child
injectors as it is stated by the current implementations of
"hierarchical injectors", but I do not like the idea of handling
multiple injectors in the application like Jesse said before.
Best regards,
Sven
On Oct 13, 10:13 pm, "[EMAIL PROTECTED]" <[EMAIL PROTECTED]> wrote:
> On Oct 13, 11:45 am, "Bob Lee" <[EMAIL PROTECTED]> wrote:
>
> > Jesse, maybe we should inject the Injector from the context, i.e. the
> > injector being used to create the current object graph? Then, we'd need only
> > one binding to Injector in the root Injector.
>
> We need to inject the Injector that owns the
> binding, not the one that's creating the graph.
> Consider a hypothetical app that has child
> injectors for the persistence and web layers:
>
> class PersistenceLayer {
> @Inject Injector injector;
> protected <T> Persister<T> getPersister(Class<T> c) {
> return injector.getInstance(c);
> }
> }
>
> class WebLayer {
> @Inject Injector injector;
> void serviceRequest(HttpRequest request) {
> Class<? implements Handler> handler =
> mapRequestToHandler(request);
> injector.getInstance(handler);
> handler.handle(request);
> }
> }
>
> If the application binding depends on both of
> these child injectors, they should be the
> appropriate ones.
>
> class Application {
> @Inject PersistenceLayer persistenceLayer;
> @Inject WebLayer webLayer;
> }
>
> This is because our model assumes that child
> injectors can promote bindings to the parent via
> hierarchical modules.
>
> Cheers,
> Jesse
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"google-guice-dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/google-guice-dev?hl=en
-~----------~----~----~----~------~----~------~--~---