Hi zhaoyi,
To answer your direct question, passing a parameter to a provider
invocation is explained here:
http://code.google.com/p/google-guice/wiki/AssistedInject
However, if your provider simply switches the returned implementation
based on a parameter, I think you should instead be writing two separate
providers and employing binding annotations as described here:
http://code.google.com/p/google-guice/wiki/BindingAnnotations
It would be easier to suggest an appropriate technique if you made your
example code a little less abstract.
Max.
(I know I posted this question in a different way in another recent
thread but it make more sense in this one.)
I'm still confused by this. In the example in the docs here for a Provider:
http://code.google.com/p/google-guice/wiki/ProviderBindings
How would you have different connection objects injected in that
constructor for the Provider. Sorry if this is totally newb, but I
don't get it.
The example then shows
public class BillingModule extends AbstractModule {
@Override
protected void configure() {
bind(TransactionLog.class)
.toProvider(DatabaseTransactionLogProvider.class);
}
What I want to do is be able to do something like (Just using the
example above for illustration, by classes are different):
//ClassA has
public void setTransactionLog(@Named("FooBar") TransactionLog transactionLog)
//ClassB has
public void setTransactionLog(@Named("Whatever") TransactionLog transactionLog)
and be able to somehow have the "FooBar" version have a different
connection than the "Whatever" version?
In my case I want to load "FooBar" and "Whatever" versions of the
provider with a different String (path to a resource file), but
stumped how to set it up I thought I could do something like:.
MyProvider myProvider = new MyProvider("file.xml");
bind(ResultOfProvider.class).annotatedWith(Names.named("FooBar")).toProvider(myProvider);
But the above doesn't seem to work. I'm probably missing something
really fundamental here, so thanks in advance.
What you're doing above seems reasonable to me - you'll need to
elaborate on "doesn't seem to work" to get help.
This ends up with sqlSession never being bound:
//SqlSessionProvider modified has constructor, takes resource file name
//Module:
SqlSessionProvider myDbProvider = new SqlSessionProvider("mydb-ibatis-config.xml");
bind(SqlSession.class).annotatedWith(Names.named("MyDB")).toProvider(myDbProvider);
//Implementation - NEVER CALLED
@Inject
public void setSqlSession(@Named("MyDB") SqlSession sqlSession) {
System.out.println("!!!!!! MyDbIbatisDao setSqlSession");
this.sqlSession = sqlSession;
}
In this later case, I never see "setSqlSession" called (and obviously my Provider get thus never called either.)
Am I declaring my setter incorrectly with the named annotation? I've even tried with field injection and no luck either.
@Inject @Named("MyDB")
protected SqlSession sqlSession;
probably a silly question, but that annotation is com.google.inject.name.Named right?
[snip]
> In this later case, I never see "setSqlSession" called (and obviously my
> Provider get thus never called either.)
I see nothing wrong with the above code, so.... when all else fails,
construct a simple example that someone else can run to demonstrate the
problem.
Here's a single .java source file which demonstrates something like what
you want:
=======================================================================
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.name.Named;
import com.google.inject.name.Names;
public class TrivialExample {
public static void main(String[] args) {
Guice.createInjector(
new FooModule()).getInstance(Injectable.class);
}
}
class Foo {
public Foo() {
System.out.println("New object constructed: " + this);
}
}
class FooProvider implements Provider<Foo> {
public FooProvider(String initThing) {
System.out.println("FooProvider created with initThing: "
+ initThing);
}
@Override
public Foo get() {
return new Foo();
}
}
class FooModule extends AbstractModule {
@Override
protected void configure() {
bind(Foo.class).annotatedWith(Names.named("wibble"))
.toProvider(new FooProvider("boing!"));
}
}
class Injectable {
@Inject
public void setSqlSession(@Named("wibble") Foo foo) {
System.out.println("Injectable injected with: " + foo);
}
}
=======================================================================
Run it, for me it *does* print "Injectable injected with: ..."
If the above doesn't give you inspiration for what might be wrong, boil
your non-working case down to a similarly small example, and post it here.
Max.