kos*_*čák 5 gwt gwt-gin dependency-injection gwt-activities
我的每个活动都需要一个对应的单例View实现.将它们注入活动的最佳策略是什么?
构造函数注入 Activity构造函数是从ActivityMapper的getActivity()调用的.ctor已经有一个参数(一个Place对象).我必须创建ActivityMapper,注入所有可能的视图.不好...
方法注入 - "在执行构造函数后自动执行注释的函数." (GWT in Action,2nd Ed.)好吧,"在执行ctor之后"显然不够快,因为当start()调用Activity的方法时,视图(或以这种方式注入的RPC服务)仍未初始化,我得到了一个NPE.
在Activity的ctor中用GWT.create构造注入器.没用,因为他们不再是单身人士.
对我们最有效的是使用Assisted 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));
Run Code Online (Sandbox Code Playgroud)
顺便说一下,要使方法注入工作,你仍然需要通过GIN创建你的活动,所以你会遇到与构造函数注入相同的问题.没有魔法,GIN不会神奇地注入它不知道的类,甚至不知道它们何时被实例化.您可以通过向Ginjector添加方法来显式触发方法注入,但我不推荐它(您的代码将取决于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);
...
Run Code Online (Sandbox Code Playgroud)
最后一句话:我不会将place对象直接传递给activity.尝试分离场所和活动,让你可以移动东西(例如,建立一个移动或平板电脑版本,你可以在主视图和详细视图之间切换,而不是并排显示它们)只需更改你的"shell"布局和你的活动地图.要真正解耦它们,你必须构建某种导航器,这将抽象你的placeController.goTo()呼叫,以便你的活动永远不会处理地方.
| 归档时间: |
|
| 查看次数: |
3229 次 |
| 最近记录: |