2012-12-17 24 views
0

我希望能夠通過輔助注入創建對象的方法的名稱發現/注入已創建的對象。通過輔助注入將創建上下文注入到guice管理的實例中

什麼,我想要做的一個例子:

// 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. 一些吉斯配置或模式,這是否
  2. 一些擴展,做的地方,我可以這樣
  3. 文檔/例子看,這將幫助我自己寫這
  4. 示例應用程序的替代模式,以完成我想要做的事

回答

0

您的真實請求,關於注入創建上下文,is not possible and will not be possible in Guice。 (direct link to bug

一對夫婦其他的想法:

  • 如果你的用例可以用只讀屬性就足夠了,使用Names.bindProperties這將使整個Properties實例(或Map<String, String>)綁定到常量並帶有適當的@Named註釋。像其他bindConstant調用一樣,這甚至會爲您或您使用convertToTypes綁定的任何其他類型轉換爲適當的原始類型。

  • 如果你只是尋找一個單獨的地圖每注入類,不要忘記,你可以編寫自己的工廠。

    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()); 
        } 
    } 
    
  • 沒有內置到吉斯將在您的Preferences接口自動反映,並創建一個bean風格的實現,其中有沒有。你可以用自由使用的dynamic proxy objects或者提供漂亮的反射支持(如GSON)來編寫自己的聰明框架。您仍然需要提供這些反射性創建的接口這樣或那樣,但我可以很容易想像這樣一個電話:

    preferences = oracle.getPrefs(Preferences.class); 
    
+0

感謝這個,其實我最後寫像FactoryModuleBuilder和我自己的類的內部FactoryProvider2,因爲我想減少樣板,因爲我需要可寫屬性。 [見這個要點](https://gist.github.com/4328225) – Matt