如何将Assisted Injected类绑定到接口?

时间:2009-10-20 16:06:31

标签: binding guice

这是我遇到的问题:

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);
     }
}

当我尝试使用以下方法获取SimpleCommand的实例时:

Guice.createInjector(new MyModule()).getInstance(CommandFactory.class).create("sample command");

我收到了这个错误:

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)

所以我的问题是当SimpleCommand具有Assisted Injected参数时,如何将SimpleCommand绑定到Executable?

这是CommandFactory及其实现:

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 个答案:

答案 0 :(得分:0)

似乎有两个问题。

一个是bind(Executable.class).to(SimpleCommand.class)。将Executable绑定到SimpleCommand意味着可以将SimpleCommand直接注入依赖于Executable的类。但由于Guice无法创建SimpleCommand本身的实例(它需要提供给工厂的辅助参数),因此绑定无效。错误消息是将@Assisted视为普通绑定注释,并尝试在构造函数中解析绑定到它的String,但没有绑定。

除此之外,似乎您正在使用Assisted Inject为Executable创建工厂,您无法在不使用某些绑定注释的情况下创建另一个绑定 。由于您正在使用辅助注入,可能您希望使用工厂创建Executable的多个实例,因此您想要直接绑定的任何个人Executable可能在您的系统中具有某些特定含义,对吧?

在这种情况下,您应该只使用一些绑定注释,如@Default和提供者方法,如下所示:

@Provides
@Default
protected Executable provideDefaultExecutable(ConfigManager configManager) {
   return new SimpleCommand(configManager, "My default command");
}