5

Guice バインディングを使用した次のコードがあります。

public class MyApplication {
    public static void main(String[] args) {
        Guice.createInjector(new AbstractModule() {
            @Override
            protected void configure() {
                bind(Foo.class).annotatedWith(Names.named("first")).toInstance(new Foo("firstFoo"));
                bind(Foo.class).annotatedWith(Names.named("second")).toInstance(new Foo("secondFoo"));

                bind(Bar.class).to(BarImpl.class);

                bind(MyApplication.class).asEagerSingleton();
            }
        });
    }

    private @Named("first") Bar first;
    private @Named("second") Bar second;

    static @Value class Foo { String name; }
    static interface Bar {}

    static class BarImpl implements Bar {
        @Inject @Named Foo foo;
    }
}

アプリケーションに注入されたBar両方の名前付き のオブジェクトを取得しようとしています。基本的には、 onとon をFoo何らかの方法で接続する必要があります。すべてを装着することからカスタムを作成することまで、いくつかの解決策を試しました。プロバイダー内の注釈の値にアクセスできないため、後者は機能しませんでした。解決策は行のどこかにあり、注釈の値を記憶するように指示していると思います。@NamedFooBar@NamedProvider@Namedbind(Bar.class).to(BarImpl.class);@Named

私の質問は、これはまったく可能ですか?

4

1 に答える 1

12

PrivateModulesを使用しています。基本的:

プライベート モジュールの構成情報は、デフォルトではその環境から隠されています。明示的に公開されたバインディングのみが、他のモジュールおよびインジェクターのユーザーに利用可能になります。詳細については、この FAQ エントリを参照してください。

使用方法は次のとおりです。

protected void configure() {
    install(new PrivateModule() {
        @Override
        protected void configure() {
            // #bind makes bindings internal to this module unlike using AbstractModule
            // this binding only applies to bindings inside this module
            bind(Foo.class).toInstance(new Foo("first"));
            // Bar's foo dependency will use the preceding binding
            bind(Bar.class).annotatedWith(Names.named("first")).to(BarImpl.class);
            // if we'd stop here, this would be useless
            // but the key method here is #expose
            // it makes a binding visible outside as if we did AbstractModule#bind
            // but the binding that is exposed can use "private" bindings
            // in addition to the inherited bindings              
            expose(Bar.class).annotatedWith(Names.named("first"));
        }
    });
    install(new PrivateModule() {
        @Override
        protected void configure() {
            bind(Foo.class).toInstance(new Foo("second"));
            bind(Bar.class).annotatedWith(Names.named("second")).to(BarImpl.class);
            expose(Bar.class).annotatedWith(Names.named("second"));
        }
    });
         bind(MyApplication.class).asEagerSingleton();
    }
}

これで、それぞれが次のように見える 2 つのバーが効果的にできました。

static class BarImpl implements Bar {
    @Inject Foo foo;
}

しかし、PrivateModules の機能により、同じ依存関係に対して異なる実装がバインドされます。

それが理にかなっていることを願っています。

于 2013-06-08T05:01:20.697 に答える