Pregunta

Estamos evaluando el uso de GIN en GWT proyecto y han tenido buenos resultados con los típicos de la inyección a través de argumentos de constructor.La cosa hemos tenido dificultad con el nivel de campo de la inyección.Los campos siempre terminan siendo nulo.¿Alguien tiene un buen ejemplo de cómo lograr presentada nivel de la inyección con GIN?

Actualización:

Aquí está el código de ejemplo similar a la nuestra:

public class MVP implements EntryPoint {

  public static final HandlerManager EVENT_BUS = new HandlerManager(null);
  private final MVPInjector _injector = GWT.create(MVPInjector.class);

  public void onModuleLoad() {
    // set up layout for module
    RootLayoutPanel.get().add(mainPanel);

    // initialize presenters
    ListPresenter listPresenter = _injector.listPresenter();
    DetailPresenter detailPresenter = _injector.detailPresenter();

    listPresenter.go(listContainer);
    detailPresenter.go(detailContainer);

    // simulate data coming in from RPC call
    EVENT_BUS.fireEvent(new DataReadyEvent(getData()));
  }
}

public class ListPresenter {

  private final HandlerManager _eventBus;
  private final Map<String, Fruit> _myRecords = new HashMap<String, Fruit>();
  private final Display _view;

  @Inject
  public ListPresenter(Display argView, HandlerManager argEventBus) {
    _eventBus = argEventBus;
    _view = argView;
  }

  public void go(HasWidgets argContainer) {
    argContainer.clear();
    argContainer.add(_view.asWidget());
  }

  public interface Display {
    public Widget asWidget();

    public void clear();

    public SingleSelectionModel<ViewProxy> getSelectionModel();

    public void setData(List<ViewProxy> argData);
  }
}

public class DetailPresenter {

  private final HandlerManager _eventBus;
  private final Display _view;
  private Fruit _myRecord;

  @Inject
  private ImagePresenterFactory _imagePresenterFactory;

  @Inject
  private TestPresenter _testPresenter;

  @Inject
  public DetailPresenter(Display argView, HandlerManager argEventBus) {
    _view = argView;
    _eventBus = argEventBus;
  }

  public void go(HasWidgets argContainer) {
    argContainer.clear();
    argContainer.add(_view.asWidget());

    if (_testPresenter != null) {
      _testPresenter.go();
    }
  }

  public interface Display {
    public Widget asWidget();

    public HasText getDescriptionControl();

    public HasClickHandlers getImageControl();

    public HasText getNameControl();

    public HasClickHandlers getSaveControl();

    public void setEnabledControls(boolean argEnabled);
  }
}

public class TestPresenter {

  @Inject
  HandlerManager _eventBus;

  public TestPresenter() {}

  public void go() {
    if (_eventBus != null) {
      _eventBus.toString();
    }
    else {
      // event bus was not injected
    }
  }
}

@GinModules(MVPModule.class)
public interface MVPInjector extends Ginjector {

  DetailPresenter detailPresenter();

  ListPresenter listPresenter();

}

public class MVPModule extends AbstractGinModule {

  @Provides
  @Singleton
  public HandlerManager getEventBus() {
    return MVP.EVENT_BUS;
  }

  @Provides
  public TestPresenter getTestPresenter() {
    return new TestPresenter();
  }

  @Override
  protected void configure() {
    bind(ListPresenter.Display.class).to(ListView.class);
    bind(DetailPresenter.Display.class).to(DetailView.class);
    bind(ImagePresenter.Display.class).to(ImagePopup.class);
    install(new GinFactoryModuleBuilder().build(ImagePresenterFactory.class));
  }

  public interface ImagePresenterFactory {
    public ImagePresenter createImagePresenter(ImageResource argImage);
  }

}

En el código anterior, me han quitado la mayor parte del código que no se trata de GIN.El TestPresenter que el DetailPresenter requiere que se inyecta correctamente pero el HandlerManager que el TestPresenter requiere siempre es null.Como se puede ver, la inyección de HandlerManager no se utiliza en el constructor.

¿Fue útil?

Solución

Actualización, buscando en el código de ejemplo:

@Provides
public TestPresenter getTestPresenter() {
  return new TestPresenter();
}

Debido a que usted está creando a sí mismo, se supone que usted haya tratado con inyecciones.Quitar este método, y se invoca el constructor por defecto (la inyección de allí, si es necesario), luego de visitar ningún otro sitio de la inyección.

Otro tema que podría estar funcionando en:hay varios HandlerManager impls, asegúrese de que todas sus referencias a HandlerManager utilizar el mismo paquete.


Original respuesta:

Serán nulos cuando el constructor se ejecuta, pero esto tiene sentido - ¿cómo podrían ser cualquier otro valor, cuando el inyector no ha tenido la oportunidad de asignar todos los campos todavía.Considerar cómo esto podría ejecutar (expresado aquí como dudosamente legal de java, ya que los campos no pueden público):

InstanceToInject instance = new InstanceToInject(...);
instance.field = provideFieldValue();

Por el momento el campo está aún elegible para ser asignado, el constructor ya se ha ejecutado.

Si el campo es nulo cuando otro método que se ejecuta, asegúrese de que el método no se ejecuta por el constructor, pero es después de la inyección ha terminado su trabajo.Otros casos en los que todavía puede ser null sería @Inject anotado incubadoras.

Suponiendo que no es ninguno de esos casos (forma más sencilla de comprobarlo es mediante el establecimiento de un punto de interrupción, y asegurándose de que el inyector no está en la pila de llamadas), asegúrese de que el campo tiene un @Inject, y que no está atado a una instancia null.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top