我在GWT教程页面上跟踪了基本设置指令。我正在进行第3步(声明绑定),并试图研究如何使用GIN的Binder。
public class MyModule extends AbstractGinModule {
@Override
public void configure() {
// 1. Declare an instance of EventBus and make sure every
// injection request pulls back the same instance.
EventBus eventBus = new EventBus();
bind(EventBus.class).to??? // no toInstance() method!
// 2. Declare two instances of Fizz using different constructors,
// and allow the injection of either of them.
Fizz f1 = new Fizz(true, "oh yeah", null);
Fizz f2 = new Fizz();
bind(Fizz.class).to??? // no toInstance() AND don't know how to choose f1 or f2!
// 3. Declare a List of Buzz objects and allow them to be
// injectable.
List<Buzz> buzzes = new ArrayList<Buzz>();
configureBuzzes(buzzes); // adds configured Buzz objects to the list
bind(???).to(buzzes); // no toInstance() methods AND how to bind List<?>.class?!
// 4. Conditionally bind SomePlace to Place *only* when we want the default Place
// that 'historyHandler.handleCurrentHistory()' will go to when called onModuleLoad.
bind(Place.class).to(SomePlace.class); // forces me to only have SomePlace instances!
}
}上面的四个用例是我正在努力解决的问题。分别:
EventBus实例?List的任何东西?Place.class提前感谢!
发布于 2012-11-16 05:39:01
好的问题,有助于阐明Guice本身是如何工作的,以及Guice和Gin之间的区别。Gin与Guice不完全一样-- configure()方法在生成JavaScript时运行,因此编译器只能在正确的类型集合中进行操作--否则应用程序可能包含整个JRE!这对Gin来说稍微有点欺骗,一旦你理解了这一点,GWT就更有意义了。
其基本思想是,configure()方法只用于处理布线,而不是创建实例。这为1)提供了答案,也给出了2的部分答案。实际上,在应用程序运行时将使用的代码(Provider对象、@Provides方法,当然还有任何带有@Inject注释的代码)需要相反的方式--它只会被编译成JS。这意味着,虽然您可以在3中定义像configureBuzzes这样的方法,但您只需要小心地从configure()方法中调用这些方法--并且永远不要从常规的应用程序代码中调用configure()。
2)、3)和4)的答案主要与Guice本身的一般工作方式有关。我所提供的解决方案也适用于普通Guice,而且我会一直建议这种方法--如果不混合布线和实际的对象构建,它往往会使代码更具可读性。
configure()方法中创建实例,只需执行绑定。可以将绑定设置为例如
bind(EventBus.class).to(SimpleEventBus.class).in(Singleton.class);
创建实例,并将其作用于单个实例-默认构造函数将在默认情况下使用。@Inject对特定的构造函数进行注释,并为每个值提供一些注释(稍后将详细介绍),或者您可以构建一个提供者或@Provides方法来创建实例。同样,您可能希望@Singleton有此意义,但这取决于您的用例(这将是您的GinModule中的另一种方法):
@提供//@Singleton //可选,取决于您的用例公共Fizz provideFirstFizz() {返回新Fizz(真,“噢,是”,null);}Fizz的代码能够得到正确的代码呢?结果可能所有这些都有相同的答案--你需要找到一种方法来指示你想要的实例。它们都是相同的类型,所以这还不够,但是我们可以提供其他提示,比如注入字段上的注释。假设我们需要f1和f2的代码如下所示
@Inject @Red//编写您自己的注释,或者使用一些现有的私有Fizz f1;@Inject @Blue私有f2;
现在我们有了一种方法来区分不同之处,我们需要使用相同的注释来绑定它们。由于我们仍然假定在@Inject构造函数上没有Fizz,所以不能只执行bind()调用,所以只需将@Blue添加到提供方法中:
@提供@Blue //@Singleton //可选,取决于您的用例公共Fizz provideFirstFizz() {返回新Fizz(真,“噢是”,null);}
我们可以将其理解为“此方法Provides Blue Fizz实例”。对于@Red,由于我们有默认的ctor,所以可以使用bind():
bind(Fizz.class).annotatedWith(Red.class);//...在这种情况下不需要指定类型//,但可能需要//singleton
有关此问题的更多细节,请参见https://code.google.com/p/google-guice/wiki/BindingAnnotations。
@Provides,或者创建和绑定Provider<T>类型。就像我们已经完成了几个提供程序方法一样,让我们尝试一个Provider<List<Buzz>>:
公共类BuzzListProvider实现了Provider { public (){ List = new ();//配置它们.这可能会调用此BuzzListProvider中定义的@Inject定义的//,在ctor或字段上调用,或//只调用此方法中的某些代码。返回蜂鸣器;}
然后,将提供程序绑定到该列表:
//不能说是List.class,使用TypeLiteral代替绑定(新的TypeLiteral(){}) .toProvider(BuzzListProvider.class);// .in(Singleton.class);如果列表只需要创建一次@DefaultPlace注释(或者只是简单的@Default,这样我就可以到处重用它)来处理这种情况。https://stackoverflow.com/questions/13408466
复制相似问题