How can i use Guice in JavaFX controllers?

老子叫甜甜 提交于 2019-12-06 05:12:11

问题


I have a JavaFX application where I would like to introduce Guice because my Code is full of factorys right now, only for the purpose of testing.

I have one use case where i have a controller class of a certain view. This controller class has a viewmodel and I pass the model to the viewmodel via the constructor of the controller class.

In the controller class I have a contactservice object that provides the edit/save/delete operations. As of now I have an interface of that object and provide an implementation and a Mock. This object can be retrieved by a Factory.getInstance() method.

What I want to do is something like this:

public class NewContactController implements Initializable {
    // ------------------------------------------------------------------------
    // to inject by guice
    // ------------------------------------------------------------------------
    private ContactService contactService;

    @Inject
    public void setContactService(ContactService srv) {
        this.contactService = srv;
    }
    // edit window
    public NewContactController(Contact c) {
        this.viewModel = new NewContactViewModel(c);
    }
    // new window
    public NewContactController() {
        this.viewModel = new NewContactViewModel();
    }

    @FXML
    void onSave(ActionEvent event) {
        //do work like edit a contcat, 
        contactService.editContact(viewModel.getModelToSave());
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        // bind to viewmodel---------------------------------------------------
    }
}

How can I achive this? Is it a good a idea to do something like that? While I was searching for a solution I found fx-guice and similar frameworks but how can i combine these two? Specially how can I let this fields be injected AND instanciate the controller myself or at least give it some constructor args?


回答1:


I don't use Guice, but the simplest approach would appear to be just to use a controller factory on the FXMLLoader. You can create a controller factory that instructs the FXMLLoader to use Guice to initialize your controllers:

final Injector injector = Guice.createInjector(...);
FXMLLoader loader = new FXMLLoader(getClass().getResource(...));
loader.setControllerFactory(new Callback<Class<?>, Object>() {
   @Override
   public Object call(Class<?> type) {
       return injector.getInstance(type);
   }
});
// In Java 8, replace the above with 
// loader.setControllerFactory(injector::getInstance);
Parent root = loader.<Parent>load();



回答2:


There's a good DI framework for javaFX called afterburner.fx. Check it out, I think it's the tool you're looking for.




回答3:


Assuming you (could) instantiate the controller by hand/guice and not from the FXML, you could use https://github.com/google/guice/wiki/AssistedInject if you need to pass any non DIable parameter to the constructor. You would then set the controller manually to the FXMLLoader with .setController(this) and load the FXML file in the constructor of the controller.

Not sure if there are any drawbacks, but this kind of system seems to work for me :)



来源:https://stackoverflow.com/questions/23471185/how-can-i-use-guice-in-javafx-controllers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!