Guice and Vaadin - How to get a reference to the Injector

Hi everyone,

I have setup the Application Servlet to be managed by Guice according to the documentation in the
wiki

All is fine but the injection works only for the Application Class (because this is the only one managed by Guice).

Example:

same as the example from the wiki


public class MyServletConfig extends GuiceServletContextListener {

  @Override
  protected Injector getInjector() {
    ServletModule module = new ServletModule(){

      @Override
      protected void configureServlets() {
          serve("/*").with(GuiceApplicationServlet.class);
          
          bind(Application.class).to(FactApplication.class).in(ServletScopes.SESSION);
          bindConstant().annotatedWith(Names.named("welcome")).to("This is my first Vaadin/Guice Application");
      }
      
    };
    
    Injector injector = Guice.createInjector(module);
    
    return injector;
  }

}


public class FactApplication extends Application {
  
  @Inject @Named("welcome") protected String text;
	@Override
	public void init() {
	  System.out.println(text); // this works
	  MainWindow mainWindow = new MainWindow(); 
		setMainWindow(mainWindow);
		
	}

}

FactApplication is managed by Guice so the injections works as expected

next:


public class MainWindow extends Window {

  private final MenuBar menubar;
  private final Panel contentPanel;
  @Inject @Named("welcome") protected String text;
  
  public MainWindow() {
    super();
    menubar = new MenuBar();
    MenuBar.MenuItem miClient = menubar.addItem("Clienti", null);
    
    MenuBar.MenuItem miAdminClient = miClient.addItem("Administrare clienti", new Command() {
      
      public void menuSelected(MenuItem selectedItem) {
        System.out.println("mainwind: " + text); // this no longer works (outputs 'null')
      }
    });
    
  }

}

When I’ve used previously Guice with Swing I had a static reference to the Injector object and every object I wanted to be managed by guice I would have instantiated with something like this:


MainWindow window  =  injector.getInstance(MainWindow.class); // instead of window = new MainWindow()...

The questions is, how do I get a reference to the Injector created in MyServletConfig ?
Or am I trying to solve this the wrong way?

If the injector reference is not the proper way, how can I make the DI work in MainWindow class?

Thank you for your time!

I think I got it. The solution is to use Providers. Like in this example:
Injecting Providers

Basically I’m instantiating the components I want managed using providers.

Hello Bogdan,

Can you please post the solution here, because I didn´t understand your solution and I have the same problem.

Regards,

Fernando

Hi Fernando,

Sorry for the late reply but I didn’t receive any notification about new replies. You probably found a solution by now, but if you’re still having troubles let me know and I’ll try to help.

Hi,

I think I have the same issue. Could you post your solution please?

Use constructor injection:


public MyWindow extends Window(){
  
    private MyService service;
  @Inject
   public MyWindow(final MyService service){
    this.service = service;
    }

}

I’ve described my use case
StackOverflow

I will try with constructor injection, but why should it work better than field injection? (even if Guice encourages you to use constructor over field injection)

Thank you very much Jari!

Injecting through constructor does work!

Does anybody knows why field injection does not work in this case?

It seems to be related to the Window class, because field injection does work for simple class. See “working-with-simple-class” tag in the
sample mercurial repo

So has anyone found out why field injection isn’t working inside Window/CustomComponent classes?

I would like to use AOP, so constructor injection is not sufficient.