我的每个事件都需要一个相应的单例 View 实现。将它们注入(inject)事件的最佳策略是什么?
start()
时, View (或以这种方式注入(inject)的 RPC 服务)仍未初始化。方法被调用,我得到一个 NPE。 最佳答案
对我们最有效的是使用辅助注入(inject)。
根据具体情况,我们在事件本身、包中(用于构建该包中的所有事件)或在 ActivityMapper 中定义事件工厂。
public class MyActivity extends AbstractActivity {
private final MyView view;
@Inject
MyActivity(MyView view, @Assisted MyPlace place) {
this.view = view;
...
}
...
}
public class MyActivityMapper implements ActivityMapper {
public interface Factory {
MyActivity my(MyPlace place);
FooActivity foo(FooPlace place);
...
}
// using field injection here, feel free to replace by constructor injection
@Inject
private Factory factory;
@Overrides
public Activity getActivity(Place place) {
if (place instance MyPlace) {
return factory.my((MyPlace) place);
} else if (place instance FooPlace) {
return factory.foo((FooPlace) place);
}
...
}
}
// in the GinModule:
install(new GinFactoryModuleBuilder().build(MyActivityMapper.Factory.class));
顺便说一句,要使方法注入(inject)起作用,您仍然必须通过 GIN 创建事件,因此您会遇到与构造函数注入(inject)相同的问题。没有魔法,GIN 不会神奇地注入(inject)它不知道甚至不知道它们何时被实例化的类。您可以通过向 Ginjector 添加方法来显式触发方法注入(inject),但我不建议这样做(您的代码将取决于 Ginjector,如果可以的话,您应该避免这样做):
interface MyGinjector extends Ginjector {
// This will construct a Foo instance and inject its constructors, fields and methods
Foo foo();
// This will inject methods and (non-final) fields of an existing Bar instance
void whatever(Bar bar);
}
...
Bar bar = new Bar("some", "arguments");
myGinjector.whatever(bar);
...
最后一句话:我不会将 place 对象直接传递给事件。尝试解耦地点和事件,这允许您移动事物(例如,构建移动或平板电脑版本,您可以在主视图和详细 View 之间切换,而不是并排显示它们)只需更改“外壳”布局和您的事件映射器。要真正将它们解耦,您必须构建某种导航器,这将抽象您的
placeController.goTo()
调用,以便您的事件永远不会涉及地点。
关于gwt - 在 GWT 事件中使用 GIN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9924695/