2009-10-20 7 views
1

Voici le problème que je rencontre:Comment lier la classe Assisted Injecté à l'interface?

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

Lorsque je tente d'obtenir par exemple de SimpleCommand en utilisant:

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

J'ai eu cette erreur:

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) 

Donc mon problème est de savoir comment puis-je lier SimpleCommand à Executable lorsque SimpleCommand a le paramètre Assisted Injected?

Voici le CommandFactory et sa mise en œuvre:

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

Qu'est-ce commandement? L'usine ne devrait-elle pas retourner Executable ou SimpleCommand? – ColinD

+1

Aussi, pourquoi avez-vous une implémentation de CommandFactory? L'idée est que Injection assistée crée l'implémentation pour vous. – ColinD

Répondre

0

Il semble y avoir deux problèmes.

On est avec bind(Executable.class).to(SimpleCommand.class). Liaison Executable à SimpleCommand implique qu'un SimpleCommand peut être injecté directement aux classes avec une dépendance sur Executable. Mais puisque Guice ne peut pas créer une instance de SimpleCommand lui-même (il a besoin du paramètre assisté fourni à l'usine), la liaison n'est pas valide. Le message d'erreur traite @Assisted comme une annotation de liaison normale et essaie de résoudre un String lié dans le constructeur, mais aucun n'est lié.

Au-delà, il semble que si vous utilisez pour créer Injecter Equipement cabinet d'une usine pour Executable s, vous ne pouvez pas créer un autre liant à elle sans utiliser une annotation de liaison sur elle. Étant donné que vous utilisez l'injection assistée, vous voulez probablement créer plusieurs instances de Executable en utilisant votre usine, de sorte que tout individu Executable que vous souhaitez lier directement aurait probablement une signification spécifique dans votre système, n'est-ce pas?

Dans ce cas, vous devez simplement utiliser une annotation de liaison comme @Default et une méthode de fournisseur comme ceci:

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