吉斯/杜松子酒.如何注入多个实现

tru*_*nka 7 gwt gwt-gin guice

我有一个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的介绍那样)工厂.对不起我的英语不好.任何帮助表示赞赏.

aid*_*nok 9

我相信你会想要使用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来在持有者之间切换.

  • +1,除了不会这样工作:你不能同时进行替换和生成,你必须创建一个带有2个子类的"InjectorServiceHolder".每一个`GWT.create()`都是一个不同的`InjectorService`子接口.您可以在"holder"上使用替换来选择要使用的InjectorService`,并且`InjectorService`子接口上的`GWT.create()`将触发GIN的代码生成. (5认同)