0

作成されたオブジェクトへのアシスト注入を介してオブジェクトを作成したメソッドの名前を発見/注入できるようにしたいと思います。

私がやりたいことの例:

// what I want guice to create the implementation for this
interface Preferences {
  Preference<String> firstName();
  Preference<String> lastName();
  // other preferences possibly of other types
}

// my interfaces and classes
interface Preference<T> {
  T get();
  void set(T value);
}
class StringPreference implements Preference<String> {
  private final Map<String, Object> backingStore;
  private final String key;
  @Inject StringPreference(@FactoryMethodName String key, 
                           Map<String, Object> backingStore) {
    this.backingStore = backingStore;
    this.key = key;
  }

  public String get() { return backingStore.get(key).toString(); }
  public void set(String value) { backingStore.put(key, value); }
}

// usage
public void exampleUsage() {
  Injector di = // configure and get the injector (probably somewhere else)
  Preferences map = di.createInstance(Preferences.class);
  Map<String, Object> backingStore = di.createInstance(...);

  assertTrue(backingStore.isEmpty()); // passes

  map.firstName().set("Bob");
  assertEquals("Bob", map.firstName().get());
  assertEquals("Bob", backingStore.get("firstName"));

  map.lastName().set("Smith");
  assertEquals("Smith", map.lastName().get());
  assertEquals("Smith", backingStore.get("lastName"));
}

残念ながら、これを実装するためにこれまでに考えた唯一の方法は、

  1. アシスト インジェクションを (コピー アンド ペーストで) 拡張して機能を追加する
  2. 私のためにそれを行う補助注射に非常に似たものを書いてください
  3. 偽りの助けを借りずにこれを行うボイラープレートをたくさん書く

次のような解決策を探しています。

  1. これを行ういくつかのguice構成またはパターン
  2. これを行う拡張機能
  3. これを自分で書くのに役立つドキュメント/場所の例
  4. 私がやりたいことを達成するためのサンプルアプリの代替パターン
4

1 に答える 1

0

作成コンテキストの注入に関する実際の要求は不可能であり、 Guice では不可能です。(バグへの直接リンク)

他のいくつかのアイデア:

  • ユースケースが読み取り専用プロパティで十分な場合は、 which を使用して、適切な注釈を使用してインスタンスNames.bindProperties全体(または) を定数にバインドできるようにします。他の呼び出しと同様に、これは適切なプリミティブ型、または を使用してバインドする他のものにキャストします。PropertiesMap<String, String>@NamedbindConstantconvertToTypes

  • 注入するクラスごとに個別の Map を探しているだけの場合は、独自のファクトリを作成できることを忘れないでください。

    class PreferenceMapOracle {
      private static final Map<Class<?>, Map<String, String>> prefMap =
          Maps.newHashMap();
    
      public Map<String, String> mapForClass(Class<?> clazz) {
        if (prefMap.contains(clazz)) {
          return prefMap.get(clazz);
        }
        Map<String, String> newMap = Maps.newHashMap();
        prefMap.put(clazz, newMap);
        return newMap;
      }
    }
    
    class GuiceUser {
      private final Map<String, String> preferences;
    
      @Inject GuiceUser(PreferenceMapOracle oracle) {
        preferences = oracle.mapForClass(getClass());
      }
    }
    
  • Guice に組み込まれているものは、Preferencesインターフェイス全体に自動的に反映されず、何もない場所に Bean スタイルの実装を作成します。おそらく、動的プロキシ オブジェクトを自由に使用するか、 GSONのような気の利いたリフレクティブ サポートを提供するパッケージを使用して、独自の巧妙なフレームワークを作成できます。これらの反射的に作成されたインターフェイスを何らかの方法で提供する必要がありますが、次のような呼び出しを簡単に想像できます。

    preferences = oracle.getPrefs(Preferences.class);
    
于 2012-12-17T23:59:32.140 に答える