在GWT活动中使用GIN
我的每个活动都需要一个相应的单例视图实现。将它们注入活动的最佳策略是什么在GWT活动中使用GIN,gwt,dependency-injection,gwt-gin,gwt-activities,Gwt,Dependency Injection,Gwt Gin,Gwt Activities,我的每个活动都需要一个相应的单例视图实现。将它们注入活动的最佳策略是什么 构造函数注入从ActivityMapper的getActivity()调用活动构造函数。ctor已经有一个参数(一个放置对象)。我必须创建包含所有可能视图的ActivityMapper。不好 方法注入-“这样注释的函数在构造函数执行后自动执行。”(GWT在运行中,第2版。)“在执行了ctor之后”显然不够快,因为在活动的start()时视图(或以这种方式注入的RPC服务)仍然没有初始化方法被调用,我得到一个NPE 在活动的
start()时视图(或以这种方式注入的RPC服务)仍然没有初始化
方法被调用,我得到一个NPE对我们最有效的方法是使用辅助注射 根据具体情况,我们在活动本身、包(用于构建该包中的所有活动)或ActivityMapper中定义了活动工厂。 顺便说一句,要使方法注入工作,您仍然必须通过GIN创建活动,因此您将遇到与构造函数注入相同的问题。没有魔法,GIN不会神奇地注入它不知道、甚至不知道何时实例化的类。您可以通过向Ginjector添加方法来显式触发方法注入,但我不建议这样做(您的代码将依赖于Ginjector,如果可以的话,这是您应该避免的):
最后一句话:我不会将place对象直接传递给活动。尝试分离位置和活动,这允许您通过更改“外壳”布局和活动映射器来移动东西(例如,构建移动或平板电脑版本,在主视图和详细视图之间切换,而不是并排显示)。要真正解耦它们,您必须构建某种导航器,它将抽象您的
placeController.goTo()
调用,以便您的活动永远不会处理位置。根据我的经验,一个好的做法是使用单独的活动映射器来处理位置和活动(映射)。在您拥有演示者的活动中,以下是一个活动示例:
public class ActivityOne extends AbstractActivity {
@Inject
private Presenter presenter;
@Override
public void start(AcceptsOneWidget panel, EventBus eventBus) {
presenter.go(panel);
}
}
演示者将视图注入其中,在调用“go”方法时构造视图(演示者)。演示者在GIN
模块中声明为singleton,视图通常是singleton(有些例外,比如出现在许多地方的小部件)
想法是将联系人与视图移动到演示者内部(因为演示者的目标是根据MVP
,处理逻辑并从视图检索/更新数据)。
在演示者内部,您还将拥有RPC
服务,您不必声明它们,因为GIN
将通过调用GWT.create“神奇地”为您创建实例
下面是一个简单演示者的示例:
public class PresenterOneImpl implements Presenter {
@Inject
private MyView view;
@Inject
private SomeRpcServiceAsync someRpc;
@Override
public void go(AcceptsOneWidget panel) {
view.setPresenter(this);
panel.setWidget(view);
updateTheViewWithData();
}
}
最后,我必须指出,有一些活动,比如菜单,直接处理位置和视图,以显示当前状态。这些活动缓存在映射器中,以避免每次更改位置时都出现新实例。我选择了一种稍微不同的方法,该方法具有您所需的所有灵活性。我不记得是从哪里学来这种设计模式的,但这不是我的主意。我创建这样的活动
public class MyActivity extends AbstractActivity{
private MyView view;
@Inject static PlaceController pc;
@Inject
public MyActivity(MyView view) {
super();
this.view = view;
}
public MyActivity withPlace(MyPlace myPlace) {
return this;
}
...
}
然后我在活动映射器中使用它,如下所示:
public class MyMapper implements ActivityMapper {
@Inject Provider<MyActivity> myActivityProvider;
public Activity getActivity(Place place) {
if ( place instanceof MyPlace){
return myActivityProvider.get().withPlace(place);
} else if
...
公共类MyMapper实现ActivityMapper{
@注入提供者myActivityProvider;
公共活动getActivity(地点){
如果(我的位置的位置实例){
返回myActivityProvider.get().withPlace(place);
}否则如果
...
还要确保视图在gin模块文件中声明为singleton。Hi Thomas,这正是我们在应用程序(使用factory)中所做的,并且工作良好。但是,您建议如何将其与gin的AsyncProvider集成以进行代码拆分?(我们使用的是ActivityAsyncProxy)
public class MyActivity extends AbstractActivity{
private MyView view;
@Inject static PlaceController pc;
@Inject
public MyActivity(MyView view) {
super();
this.view = view;
}
public MyActivity withPlace(MyPlace myPlace) {
return this;
}
...
}
public class MyMapper implements ActivityMapper {
@Inject Provider<MyActivity> myActivityProvider;
public Activity getActivity(Place place) {
if ( place instanceof MyPlace){
return myActivityProvider.get().withPlace(place);
} else if
...