【问题标题】:how to inject a uiBinder with @Inject (instead of GWT.create())?如何使用@Inject(而不是 GWT.create())注入 uiBinder?
【发布时间】:2013-08-23 17:14:25
【问题描述】:

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

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();
    }
}

除了没有参数的类之外还需要什么?在我公司的项目中,相同类型的代码在其他地方也可以使用。抱歉,这里的菜鸟水平很高... 如果各位大神指点一下就好了。

谢谢

【问题讨论】:

    标签: gwt guice code-injection uibinder gwtp


    【解决方案1】:

    两个问题:

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

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

    【讨论】:

    • 谢谢,requestStaticInjection 是我错过的东西。我本可以将 uiBinder 放在构造函数中,但在我的情况下,视图是手动构造的。
    • 在这种情况下,您可能不想打扰构造函数上的 @Inject 注释,因为它似乎表明它将由 gin/guice 管理。
    【解决方案2】:

    要有一个由 GIN 生成的类(不管它是否是 uiBinder),它没有必要有一个默认的构造函数(即没有参数的构造函数)。您要注入的类必须具有带有@Inject 注解的构造函数:

    @Inject
    public InjectMeClass(Object a, Object b)
    

    另一个被注入的类,假设它是一个UiBinder,注入的字段必须用@UiField(provided=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");
        }
    

    【讨论】:

    • 感谢您提供这些信息。 Gin 提供者是否与 UIFactory 相同?
    • 从概念上讲,它们是完全不同的东西。实际上,正如您正确指出的那样,它们做同样的事情:实现构建对象的逻辑。 GIN 是依赖注入设计模式的一种实现。 UiFactory 实现了工厂模式。根据我的经验,熟悉依赖注入需要更多时间,但在实践中,我现在发现构建系统中使用的对象并保持代码干净非常强大。
    猜你喜欢
    • 2011-11-26
    • 1970-01-01
    • 2011-05-07
    • 1970-01-01
    • 1970-01-01
    • 2021-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多