问题
Here is the problem I met:
Class SimpleCommand implements Executable{
private final ConfigManager config;
private String name;
@Inject
public SimpleCommand(ConfigManager config, @Assisted String name){
this.config = config;
this.name = name;
}
}
Class MyModule extends AbstractModule{
@Override
protected void configure() {
bind(CommandFactory.class).toProvider(FactoryProvider.newFactory(CommandFactory.class, SimpleCommand.class));
bind(Executable.class).to(SimpleCommand.class);
}
}
When I try to get instance of SimpleCommand using:
Guice.createInjector(new MyModule()).getInstance(CommandFactory.class).create("sample command");
I got this error:
1) No implementation for java.lang.String annotated with @com.google.inject.assistedinject.Assisted(value=) was bound.
while locating java.lang.String annotated with @com.google.inject.assistedinject.Assisted(value=)
for parameter 2 at model.Command.<init>(SimpleCommand.java:58)
at module.MyModule.configure(MyModule.java:34)
So my problem is how can I bind SimpleCommand to Executable when SimpleCommand has Assisted Injected parameter?
Here is the CommandFactory and its implementation:
public interface CommandFactory{
public Command create(String name);
}
public class GuiceCommandFactory implements CommandFactory{
private Provider<ConfigManager> configManager ;
@Inject
public GuiceCommandFactory(Provider<ConfigManager> configManager){
this.configManager = configManager;
}
public Command create(String cmd){
return new Command(configManager.get(), cmd);
}
}
回答1:
There seem to be two problems.
One is with bind(Executable.class).to(SimpleCommand.class)
. Binding Executable
to SimpleCommand
implies that a SimpleCommand
can be injected directly to classes with a dependency on Executable
. But since Guice cannot create an instance of SimpleCommand
itself (it needs the assisted parameter provided to the factory), the bind is invalid. The error message is treating @Assisted
as a normal binding annotation, and trying to resolve a String
bound to it in the constructor, but none is bound.
Beyond that, it seems like if you're using Assisted Inject to create a factory for Executable
s, you can't create another binding to it without using some binding annotation on it. Since you're using assisted inject, presumably you want to create multiple instances of Executable
using your factory, so any individual Executable
you wanted to bind directly would probably have some specific meaning in your system, right?
In that case, you should just use some binding annotation like @Default
and a provider method like so:
@Provides
@Default
protected Executable provideDefaultExecutable(ConfigManager configManager) {
return new SimpleCommand(configManager, "My default command");
}
来源:https://stackoverflow.com/questions/1595723/how-to-bind-assisted-injected-class-to-interface