One other option is the use of a child injector, rather than a custom scope. I'm sorry that I don't have time to elaborate but perhaps someone else on this list could.
Basically, in the place where you need the custom (or different) binding you could create a child injector from the main one, overriding the default binding in a custom module and passing this to the child injector via Modules.override(). -Russ On Thu, Dec 9, 2010 at 9:40 AM, Ryan <[email protected]> wrote: > Fred, > > Thank you for the prompt response! I spent some time last night > playing with your suggestion, and I was able to get it to work. > However, I was hoping to find a solution that didn't require the extra > work of a custom scope, with the intrusion of the framework into my > domain code. This is not a webapp, and using RequestScoped doesn't > really make sense in this context either. > > I'm wondering if there's a possible solution that could be confined to > annotations and the Provider interface alone, with the rest of the > configuration in modules. Am I barking up the wrong tree? > > Thanks, > Ryan > > On Dec 8, 5:49 pm, Fred Faber <[email protected]> wrote: > > When I hear that a dependency depends on a runtime value I immediately > think > > about binding the value in scope. You can then manually seed the value > > upstream before you traverse the downstream call graph. > > > > Something like: > > > > D d = getD(); > > simpleScope.seed(D.class, d); > > doSomethingThatRequiresD(); > > > > ... > > > > class DependsOnD { > > // Inject a provider this class is created before D is in scope > > @Inject Provider<D> dProvider; > > ... > > void useD() { > > dProvider.get().doSomething(); > > } > > > > } > > > > ... > > > > // Or you might have your own scope > > bind(D.class).in(RequestScoped.class); > > > > -Fred > > > > > > > > > > > > > > > > On Wed, Dec 8, 2010 at 7:42 PM, Ryan <[email protected]> wrote: > > > Hello everyone, > > > > > Been an avid user of Guice for a while now, and just ran across a new > > > situation that has me stumped. I've got a dependency that I need to > > > be able to change at runtime. The catch is, the piece of code that > > > needs it is far down the call graph from where it changes. I've > > > attempted to use assisted inject to let me customize the object at > > > runtime, but there's a hitch. > > > > > An example will make this more clear: > > > > > class MyModule extends AbstractModule { > > > protected void configure() { > > > > > bind( BFactory.class ).toProvider( FactoryProvider.newFactory( > > > BFactory.class, > > > B.class ) ); > > > } > > > } > > > > > interface BFactory { > > > B create( D d ); > > > } > > > > > class A { > > > @Inject BFactory bFac; > > > > > void executeA( D d ) { > > > bFac.create( d ).executeB(); > > > } > > > } > > > > > class B { > > > @Inject C c; > > > > > void executeB() { > > > c.executeC(); > > > } > > > } > > > > > class C { > > > @Inject @Assisted D d; > > > > > public void executeC() { > > > System.out.println( d ); > > > } > > > } > > > > > class D {}; > > > > > Now I can call A.executeA() with different instances of D (which is > > > needed by C) at runtime. Executing the above classes with the > > > following code,two different D objects are written to stdout as > > > expected: > > > > > A a = i.getInstance( A.class ); > > > a.executeA( new D() ); > > > a.executeA( new D() ); > > > > > This works as long as I only create C through the BFactory, and as > > > long as everything is concrete. But if I introduce an interface, > > > there's a problem, as follows: > > > > > class MyModule extends AbstractModule { > > > protected void configure() { > > > > > bind( BFactory.class ).toProvider( FactoryProvider.newFactory( > > > BFactory.class, > > > B.class ) ); > > > bind( C.class ).to( CImpl.class ); > > > } > > > } > > > > > interface C { > > > void executeC(); > > > } > > > > > class CImpl implements C { > > > @Inject @Assisted D d; > > > > > public void executeC() { > > > System.out.println( d ); > > > } > > > } > > > > > This gives me an error: > > > > > 1) No implementation for D annotated with > > > @com.google.inject.assistedinject.Assisted(value=) was bound. > > > while locating D annotated with > > > @com.google.inject.assistedinject.Assisted(value=) > > > for field at CImpl.d(AssistedInjectTest.java:62) > > > at MyModule.configure(AssistedInjectTest.java:28) > > > > > The BFactory binding is still okay, but the C->CImpl binding is what > > > produces the error. I assume this is because class C could > > > conceivably be wired into another class as a dependency (in addition > > > to class B) and Guice wouldn't know what to do with the dependency on > > > D. > > > > > What's the best solution to this? Am I making it needlessly complex? > > > I need to know if there's a way to supply D to C without B knowing > > > anything about it, while still allowing A to change what D is. > > > > > Thanks, > > > Ryan > > > > > -- > > > You received this message because you are subscribed to the Google > Groups > > > "google-guice" group. > > > To post to this group, send email to [email protected]. > > > To unsubscribe from this group, send email to > > > [email protected]<google-guice%[email protected]> > <google-guice%2bunsubscr...@google groups.com> > > > . > > > For more options, visit this group at > > >http://groups.google.com/group/google-guice?hl=en. > > -- > You received this message because you are subscribed to the Google Groups > "google-guice" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]<google-guice%[email protected]> > . > For more options, visit this group at > http://groups.google.com/group/google-guice?hl=en. > > -- You received this message because you are subscribed to the Google Groups "google-guice" 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?hl=en.
