我有一个webapp,它使用GIN在入口点注入依赖项.
private InjectorService injector = GWT.create(InjectorService.class);
Run Code Online (Sandbox Code Playgroud)
@GinModules({PlaceContollerInject.class, RootViewInject.class})
public interface InjectorService extends Ginjector {
RootView getRootView();
PlaceController getPlaceConroller();
}
Run Code Online (Sandbox Code Playgroud)
public class RootViewInject extends AbstractGinModule {
@Override
protected void configure() {
bind(RootView.class).to(RootViewImpl.class);
}
}
Run Code Online (Sandbox Code Playgroud)
我需要一个使用不同RootView实现的移动版本.依赖关系在以下模块中描述
public class RootViewMobileInject extends AbstractGinModule {
@Override
protected void configure() {
bind(RootView.class).to(RootViewMobileImpl.class);
}
}
Run Code Online (Sandbox Code Playgroud)
问题是如何有条件地选择所需的依赖性是否需要移动版或默认版.我见过GWT-GIN多重实现,但还没有找到解决方案,因为Provider打破了依赖关系链,而Factory Pattern破坏了可测试性.在这里的"Big Modular Java with Guice"视频中(12分钟) Guice的带模块的注射器被用作工厂的替代品.所以我的问题是我应该为我的应用程序的移动和默认版本(如MobileFactory和DefaultFactory)创建不同的Ginjector,否则这将是不好的做法,我应该配置一个Ginjector实例,其中包含所有需要的版本.例如,使用这样的注释绑定.
public class RootViewMobileInject extends AbstractGinModule {
@Override
protected void configure() {
bind(RootView.class).annotatedWith(Mobile.class).to(RootViewMobileImpl.class);
}
}
Run Code Online (Sandbox Code Playgroud)
并在GWT入口点使用@Mobile注释绑定
@Inject
private void setMobileRootView(@Mobile RootView rw) {
this.rw = rw;
}
Run Code Online (Sandbox Code Playgroud)
在如上所述的简化示例中,可能是可能的.但是,如果应用程序具有更多需要移动和默认版本的依赖项.看起来好像回到了不可测试的"丑陋"(就像Guice的介绍那样)工厂.对不起我的英语不好.任何帮助表示赞赏.
我相信你会想要使用GWT延迟绑定,使用类替换来绑定不同版本的InjectorService,具体取决于用户代理.这将确保移动版本仅具有编译(和下载)的移动实现
所以你会有InjectorServiceDesktop,InjectorServiceMobile,它们都从InjectorService扩展,然后是GWT.create(InjectorService.class),让延迟绑定决定它应该使用哪个实现.
http://code.google.com/webtoolkit/doc/latest/DevGuideCodingBasicsDeferred.html#replacement
所有版本的Ginjector的一个实例看起来很糟糕,因为它意味着两个版本的所有代码总是被下载(并且您当然不希望将所有桌面视图下载到您的移动应用程序中)
编辑:正如Thomas在评论中指出的那样,由于Injectors是生成类,你需要将每个InjectorServiceXXX放在一个简单的holder类中,GWT.create()是InjectorServiceXXX,并使用replace来在持有者之间切换.