GWT GIN字段级别注入 [英] GWT GIN Field Level Injection

查看:134
本文介绍了GWT GIN字段级别注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们在GWT项目中使用GIN进行评估,并且通过构造函数参数进行典型注入,结果很好。我们遇到的困难是现场级别的注入。这些字段总是最终为空。有没有人有一个很好的例子,说明如何正确实现GIN的注册级别注入?



更新:

是类似于我们的一些示例代码:

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(){
//设置模块$ b $的布局b $ RootLayoutPanel.get()。add(mainPanel);

//初始化演示者
ListPresenter listPresenter = _injector.listPresenter();
DetailPresenter detailPresenter = _injector.detailPresenter();

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

//模拟来自RPC调用的数据
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(显示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;
私人水果_myRecord;

@Inject
private ImagePresenterFactory _imagePresenterFactory;

@Inject
private TestPresenter _testPresenter;

@Inject
public DetailPresenter(显示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();

公共HasText getDescriptionControl();

公共HasClickHandlers getImageControl();

公共HasText getNameControl();

公共HasClickHandlers getSaveControl();

public void setEnabledControls(boolean argEnabled);



public class TestPresenter {

@Inject
HandlerManager _eventBus;
$ b $ public TestPresenter(){}

public void go(){
if(_eventBus!= null){
_eventBus.toString();
}
else {
//事件总线未被注入
}
}
}

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

DetailPresenter detailPresenter();

ListPresenter listPresenter();



public class MVPModule extends AbstractGinModule {

@Provides
@Singleton
public HandlerManager getEventBus(){
返回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);
}

}

在上面的代码中,我有删除了大部分不涉及GIN的代码。 DetailPresenter需要的TestPresenter被成功注入,但TestPresenter要求的HandlerManager始终为空。正如你所看到的,注入的HandlerManager不在构造函数中使用。

解决方案

更新,查看示例代码:

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

$ / code>

因为你自己创建它,它假定你已经处理了任何注入。删除这个方法,它会调用默认的构造函数(如果需要,在那里注入),然后访问任何其他注入站点。



另一个问题可能会遇到:那里是几个HandlerManager impls,请确保您对HandlerManager的所有引用都使用相同的包。






原始答案:



在构造函数运行时它们将为null,但这是有道理的 - 当注入器尚未有机会分配所有字段时,它们又怎么可能是任何其他值。考虑这可能会如何运行(这里表示为可疑的合法java,因为字段可能不公开):

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

当字段有资格分配时,您的构造函数已经运行。



如果在另一个方法运行时该字段为空,请确保该方法不由构造函数运行,而是在注入完成其工作之后。其他情况下,它可能为null将是 @Inject 带注释的setter。



假设它们都不是这些情况(最简单的检查方法是设置一个断点,并确保注入器不在调用堆栈中),确保该字段确实有一个 @Inject ,并且它不绑定到空实例。


We are evaluating using GIN in out GWT project and have had good results with typical injection via constructor arguments. The thing we have had difficulty with is field level injection. The fields always end up being null. Does anyone have a good example of how to properly achieve filed level injection with GIN?

Update:

Here is some example code similar to ours:

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

}

In the above code, I have removed most of the code that doesn't involve GIN. The TestPresenter that the DetailPresenter requires is injected successfully but the HandlerManager that the TestPresenter requires is always null. As you can see, the injected HandlerManager is not used in the constructor.

解决方案

Update, looking at sample code:

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

Because you are creating it yourself, it assumes you've dealt with any injections. Remove this method, and it will invoke the default constructor (injecting there if needed), then visit any other injection site.

One other issue you could be running into: there are several HandlerManager impls, make sure all of your references to HandlerManager use the same package.


Original answer:

They will be null when the constructor is running, but this makes sense - how could they be any other value, when the injector hasn't had a chance to assign all the fields yet. Consider how this could would run (expressed here as questionably legal java, as fields may not be public):

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

By the time the field is even eligible to be assigned, your constructor has already run.

If the field is null when another method is run, make sure that method is not being run by the constructor, but is after injection has finished its work. Other cases where it may yet be null would be @Inject annotated setters.

Assuming it is none of those cases (easiest way to check is by setting a breakpoint, and making sure the injector isn't in the call stack), be certain that the field does have an @Inject, and that it isn't bound to a null instance.

这篇关于GWT GIN字段级别注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆