如何使用@Inject(而不是GWT.create())注入uiBinder?

时间:2013-08-23 17:14:25

标签: gwt guice code-injection uibinder gwtp

首先,做这样的事情是一个好习惯吗? 我尝试了对我来说似乎是正确的方法,但没有成功:

public class FormViewImpl extends CompositeView implements HasUiHandlers<C>, FormView {
    public interface SettlementInstructionsSearchFormViewUiBinder extends UiBinder<Widget, SettlementInstructionsSearchFormViewImpl> {}

    @Inject
    static FormViewImpl uiBinder;

    @Inject
    static Provider<DateEditorWidget> dateEditorProvider;

    @UiField(provided = true)
    MyComponent<String> myComp;

    @UiField
    DateEditorWidget effectiveDateFrom;

    // .. other fields

    @Inject
    public FormViewImpl () {
        myComp = new MyComponent<String>("lol");

        if (uiBinder == null)
            uiBinder = GWT.create(SettlementInstructionsSearchFormViewUiBinder.class);

        initWidget(uiBinder.createAndBindUi(this));
    }

    @UiFactory
    DateEditorWidget createDateEditor() {
        return dateEditorProvider.get();
    }
}

除了没有参数的类还需要什么?在我公司的项目中,同样的代码可以在其他地方使用。对不起,这里有高水平的菜鸟...... 如果你们有任何指针,那就太好了。

由于

2 个答案:

答案 0 :(得分:4)

两个问题:

首先,你的两个@Inject字段是静态的 - 你有没有做任何事情来注入静态字段?当Gin(或Guice)创建新实例时,静态字段不会被设置,必须设置一次并完成。因为它们是静态的,所以它们永远不会被垃圾收集 - 这可能对您没用,或者它可能是一个问题,您应该将它们更改为实例字段。如果你想让它们保持静态,那么你必须在你的模块中调用requestStaticInjection来要求Gin在创建ginjector时初始化它们。

接下来,如果您确实选择删除静态,则uiBinder字段在该构造函数中仍必须为null,因为尚未注入字段!如何在尚未创建的对象上设置字段?这就是你期望Gin能够做到的。相反,请考虑将其作为参数传递给@Inject装饰构造函数。您甚至不需要将其另存为字段,因为窗口小部件只会使用一次。

答案 1 :(得分:1)

要生成由GIN生成的类(如果它是uiBinder则无关紧要),它没有必要具有默认构造函数(即没有参数的构造函数)。要注入的类必须具有使用@Inject注释的构造函数:

@Inject
public InjectMeClass(Object a, Object b)

注入的另一个类,假设它是一个UiBinder,必须注入用@UiField注释的字段(提供= true):

public class Injected extends Composite {

    private static InjectedUiBinder uiBinder = GWT
            .create(InjectedUiBinder.class);

    interface InjectedUiBinder extends UiBinder<Widget, Injected> {
    }

    @UiField(provided=true)
    InjectMeClass imc;

    public Injected(final InjectMeClass imc) {
        this.imc=imc;
        initWidget(uiBinder.createAndBindUi(this));
    }

所以,回到你的情况:

    @UiField(provided = true)
    MyComponent<String> myComp;

    @Inject
    public FormViewImpl (MyComponent<String> myComp) {
        this.myComp = myComp;

,例如:

   public class MyComponent<T> extends Composite {
        private T value;

        @Inject
        public MyComponent(T t) {
            this.value = t;
            ...
        }
        ...
    }

在GIN模块中,您可以拥有提供者:

    @Provides
    @Singleton
    public MyComponent<String> createMyComponent() {
        return new MyComponent<String>("lol");
    }