web-dev-qa-db-ja.com

1つの実装をGoogleGuiceのいくつかのインターフェースにバインドするにはどうすればよいですか?

2つのインターフェイスの実装として1つのクラスをバインドする必要があります。また、シングルトンスコープでバインドする必要があります。

私がしたこと:

bind(FirstSettings.class).
    to(DefaultSettings.class).
    in(Singleton.class);
bind(SecondSettings.class).
    to(DefaultSettings.class).
    in(Singleton.class);

ただし、明らかに、2つの異なるインスタンスが作成されます。これは、それらが異なるキーにバインドされているためです。

私の質問はどうすればそれができるのかということです。

32
Pavel

Guiceのwikiには このユースケースに関するドキュメント があります。

基本的に、これはあなたがすべきことです:

// Declare that the provider of DefaultSettings is a singleton
bind(DefaultSettings.class).in(Singleton.class);

// Bind the providers of the interfaces FirstSettings and SecondSettings
// to the provider of DefaultSettings (which is a singleton as defined above)
bind(FirstSettings.class).to(DefaultSettings.class);
bind(SecondSettings.class).to(DefaultSettings.class);

追加のクラスを指定する必要はありません。Providersの観点から考えるだけで、答えはかなり自然に得られます。

56

私が見つけた解決策は次のとおりです。

bind(FirstSettings.class).
    to(DefaultSettings.class).
    in(Singleton.class);
bind(SecondSettings.class).
    to(FirstSettings.class).
    in(Singleton.class);

SecondSettingsがFirstSettingsを拡張するので、私の場合は機能します。

4
Pavel

したがって、DefaultSettingsFirstSettingsSecondSettingsの両方の実装です。つまり、次のようになります。

public class DefaultSettings implements FirstSettings, SecondSettings
{
}

クラスEngineAEngineBがあるとしましょう

public class EngineA
{
    @Inject
    private FirstSettings settings;
}

public class EngineB
{
    @Inject
    private SecondSettings settings;
}

同じ実装を注入したいとします。

インターフェイスを宣言できますDefaultSettingsInterface

public interface DefaultSettingsInterface extends FirstSettings, SecondSettings
{
}

DefaultSettingsDefaultSettingsInterfaceを実装させます

public class DefaultSettings implements DefaultSettingsInterface
{
}

その場合、構成は次のようになります。

bind(FirstSettings.class).to(DefaultSettingsInterface.class);
bind(SecondSettings.class).to(DefaultSettingInterface.class);
bind(DefaultSettingsInterface.class).to(DefaultSettings.class).in(Singleton.class);
2
Boris Pavlović