我们正在评估 GWT 项目中使用 GIN 的情况,并通过构造函数参数进行典型注入,取得了良好的结果。我们遇到的困难是现场级注入。这些字段最终总是为空。有没有人有一个很好的例子来说明如何使用 GIN 正确实现字段级注入?
Update:
这是一些与我们类似的示例代码:
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);
}
}
上面的代码中,我去掉了大部分不涉及GIN的代码。 DetailPresenter需要的TestPresenter注入成功,但是TestPresenter需要的HandlerManager始终为null。可以看到,构造函数中并没有使用注入的HandlerManager。
更新,查看示例代码:
@Provides
public TestPresenter getTestPresenter() {
return new TestPresenter();
}
因为您是自己创建的,所以它假设您已经处理过任何注入。删除此方法,它将调用默认构造函数(如果需要,则在那里注入),然后访问任何其他注入站点。
您可能遇到的另一个问题是:有多个 HandlerManager 实现,请确保对 HandlerManager 的所有引用都使用相同的包。
原答案:
当构造函数运行时它们将为 null,但这是有道理的 - 当注入器还没有机会分配所有字段时,它们怎么可能是任何其他值。考虑一下这将如何运行(这里表示为有问题的合法 java,因为字段可能不是公共的):
InstanceToInject instance = new InstanceToInject(...);
instance.field = provideFieldValue();
当该字段甚至可以被分配时,您的构造函数已经运行。
如果运行另一个方法时该字段为空,请确保该方法没有运行由构造函数,但是是在注入完成其工作之后。其他可能为空的情况是@Inject
带注释的设置器。
假设不是这些情况(最简单的检查方法是设置断点,并确保注入器不在调用堆栈中),请确保该字段确实有一个@Inject
,并且它不绑定到 null 实例。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)