2011-04-19 16 views
2

這裏的情況:我有一個抽象類具有構造函數的布爾(控制某些緩存行爲):注漿生成的類,而無需編寫過多的模塊配置代碼

abstract class BaseFoo { protected BaseFoo(boolean cache) {...} } 

的實現都產生源代碼(其中許多是幾十個)。我想自動爲它們創建綁定,即沒有爲每種綁定類型明確的手工編碼。我希望注入站點能夠指定緩存或非緩存(true/false ctor參數)。比如我可能有兩次注射,如:

DependsOnSomeFoos(@Inject @NonCaching AFoo aFoo, @Inject @Caching BFoo bFoo) {...} 

(可以說這是一個不好的事,既然決定緩存與否可能更是一個模塊中,但它給什麼我的工作似乎是有用的。 。)

接下來的問題是:什麼是配置綁定產生設置生成的類型的以統一的方式最好的方式,支持對具體類綁定註釋以及構造PARAM ?

以前我只是在實現類上有一個默認的構造函數,只是在每個生成的接口上放置@ImplementedBy。例如: -

// This is all generated source... 
@ImplementedBy(AFooImpl.class) 
interface AFoo { ... } 

class AFooImpl extends BaseFoo implements AFoo { AFooImpl() { super(true); } } 

但是,現在我想允許,如果真或假傳遞給BaseFoo單獨注入點來決定,而不是它總是默認設置爲true。我試圖建立一個注入監聽器(偷偷地)改變構造後的真/假值,但我無法看到如何「注視」注入某個註釋的類型的範圍

我不斷回來的問題是綁定需要針對特定​​類型,但我不想枚舉所有類型的集中。

我也認爲:

  1. 編寫某種掃描器發現所有生成的類,並添加一對綁定的爲他們每個人,也許是使用谷歌的思考。
  2. 創建額外的,不重要的「非緩存」類型(例如AFoo.NoCache擴展AFoo),這將允許我回到@ImplementedBy。
  3. 將每種特定類型的硬接線在生成時配置爲緩存/非緩存。

我對任何這些想法都感覺不太好。有沒有更好的辦法?


更新:感謝您的評論和答覆。我認爲在每種類型的旁邊生成一個小模塊,並在運行時通過getResources寫出一個模塊列表以獲得勝利。

這就是說,在與同事交談之後,我們可能只是在提出問題時躲開問題,而是用類似boolean shouldCache(Class<? extends BaseFoo> c)的方法將策略對象注入到每個生成的類中。該策略可以在應用程序配置之上實現,並提供粗粒度和細粒度控制。這放棄了注射部位改變行爲的要求。另一方面,我們不需要額外的模塊。

+0

經過推斷,我找不到任何方法來實現你想要的,除了你提出的解決方案。在這三種解決方案中,我認爲第二種解決方案並不錯:將它添加到代碼生成中並不難,它很容易使用(在您希望注入的方法中)並且可讀。如果有的話,我會非常有興趣看到另一個更適合Guice的解決方案。 – jfpoilpret 2011-04-19 09:16:58

回答

1

有一下兩個額外的方法(除了你所提到的):

  1. 進樣工廠類,而不是你的真實類的;也就是說,你的手編碼的東西最終會說:

    @Inject 
    DependsOnSomeFoos(AFoo.Factory aFooFactory, BFoo.Factory bFooFactory) { 
        AFoo aFoo = aFooFactory.caching(); 
        BFoo bFoo = bFooFactory.nonCaching(); 
        ... 
    } 
    

    和生成的代碼會說:

    // In AFoo.java 
    interface AFoo { 
        @ImplementedBy(AFooImpl.Factory.class) 
        interface Factory extends FooFactory<AFoo> {} 
        // ... 
    } 
    
    // In AFooImpl.java 
    class AFooImpl extends BaseFoo implements AFoo { 
        AFooImpl(boolean caching, StuffNeededByAFIConstructor otherStuff) { 
        super(caching); 
        // use otherStuff 
        } 
        // ... 
        class Factory implements AFoo.Factory { 
        @Inject Provider<StuffNeededByAFIConstructor> provider; 
        public AFoo caching() { 
         return new AFooImpl(true, provider.get()); 
        } 
        // ... 
        } 
    } 
    

    當然,這取決於接口FooFactory:

    interface FooFactory<T> { 
        T caching(); 
        T nonCaching(); 
    } 
    
  2. 修改您的代碼生成過程以生成您在應用程序設置中使用的Guice模塊。我不知道代碼生成當前是如何構建的,但是如果在代碼生成時您可以通過某種方式瞭解完整的類集,則可以直接執行此操作,也可以將其附加到某個文件,然後可以將其作爲零件加載到ClassLoader.getResources Guice模塊自動發現要綁定的類。

+0

感謝您的徹底解答。同樣的工廠理念也出現在我身上,但我被它笨拙的感覺和生成的類中添加的垃圾郵件拖延了。使用'ClassLoader.getResources'來獲取模塊列表的提示具有各種意義,並且即使對於多組生成的代碼也可以工作。 – CJC 2011-04-27 08:43:09

相關問題