Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using @Assisted inject with multiple params of same Type (@Named params)

Tags:

my problem boils down to using @Assisted with two string arguments to the factory. The problem is that because Guice treats type as the identification mechanism for parameters, both parameters are the same, and I get a configuration error.

Some Code:

public class FilePathSolicitingDialog {      //... some fields      public static interface Factory {         public FilePathSolicitingDialog make(Path existingPath,                                              String allowedFileExtension,                                              String dialogTitle);     }      @Inject     public FilePathSolicitingDialog(EventBus eventBus,                                     SelectPathAndSetTextListener.Factory listenerFactory,                                     FilePathDialogView view,                                     @Assisted Path existingPath,                                     @Assisted String allowedFileExtension,                                     @Assisted String dialogTitle) {         //... typical ctor, this.thing = thing     }      // ... methods } 

The problem lies in the double-strings parameters.

I've tried tagging each string with separate @Named("as appropriate") annotations, but that just leads to more configuration errors. From the sound of those errors they don't want binding annotations on the factory class, so I have not tried custom binding annotations.

The simple and noisy solution is to create a simple argument class to contain those three assisted values, and simply inject that:

    public static class Config{         private final Path existingPath;         private final String allowedFileExtension;         private final String dialogTitle;          public Config(Path existingPath, String allowedFileExtension, String dialogTitle){             this.existingPath = existingPath;             this.allowedFileExtension = allowedFileExtension;             this.dialogTitle = dialogTitle;         }     }      public static interface Factory {         public FilePathSolicitingDialogController make(Config config);     }      @Inject     public FilePathSolicitingDialogController(EventBus eventBus,                                               SelectPathAndSetTextListener.Factory listenerFactory,                                               FilePathDialogView view,                                               @Assisted Config config) {         //reasonably standard ctor, some this.thing = thing         // other this.thing = config.thing     } } 

This works and is likely to be fairly bug-free but is noisy. Some way to get rid of that nested static class would be nice.

Thanks for any help!

like image 806
Groostav Avatar asked May 08 '14 22:05

Groostav


1 Answers

Have a look at this documentation (previously here):

Making parameter types distinct

The types of the factory method's parameters must be distinct. To use multiple parameters of the same type, use a named @Assisted annotation to disambiguate the parameters. The names must be applied to the factory method's parameters:

public interface PaymentFactory {    Payment create(        @Assisted("startDate") Date startDate,        @Assisted("dueDate") Date dueDate,        Money amount);  } 

...and to the concrete type's constructor parameters:

public class RealPayment implements Payment {    @Inject    public RealPayment(       CreditService creditService,       AuthService authService,       @Assisted("startDate") Date startDate,       @Assisted("dueDate") Date dueDate,       @Assisted Money amount) {      ...    }  } 
like image 173
condit Avatar answered Sep 20 '22 12:09

condit