2011-09-14 60 views
1

我有一些代碼讀取這樣的:如何很好地處理與Guice的構造函數中檢查的異常?

class A { 
    X x; 

    A() { 
    Class<? extends X> cls = ...; 
    Module module = ...; 
    Injector injector = Guice.createInjector(module); 
    x = injector.getInstance(cls); 
    } 
} 

具體類型cls僅在運行時確定的,該構造函數被調用之前不知道的。

我現在的問題是,cls的構造函數預計會拋出檢查異常,並且我想要處理它們(如果可能的話,不要從ProvisionException中解開它們)。 Guice文檔說我應該使用投擲提供者擴展,這在這裏似乎很複雜。有沒有一種簡單的方法莫過於:

interface MyCheckedProvider<T> extends CheckedProvider<T> { 
    T get() throws MyCheckedException; 
} 

class XImplProvider implements MyCheckedProvider<X> { 
    @Inject dependency1; 
    @Inject dependency1; 

    X get() throws MyCheckedException { 
    return new XImpl(dependency1, dependency2); 
    } 
} 

class ProviderHolder { 
    @Inject MyCheckedProvider<X> provider; 
} 

class A { 
    X x; 

    A() { 
    Class<? extends MyCheckedProvider<X>> providerClass = ...; 
    Module module = new AbstractModule() { 
     void configure() { 
     ... 
     ThrowingProviderBinder.create(binder()) 
      .bind(MyCheckedProvider.class, X.class) 
      .to(providerClass.class); 
     } 
    }; 

    Injector injector = Guice.createInjector(module); 
    ProviderHolder holder = injector.getInstance(ProviderHolder.class); 
    try { 
     x = holder.provider.get(); 
    catch (MyCheckedException e) { 
     ... 
    } 
    } 
} 

接口MyCheckedProvider將是確定的,因爲它會在幾個地方可重複使用的,但我需要一個單獨的ProviderHolder類在每一個地方需要類似的地方,我需要爲每個實現X的類實現一個特定的提供者實現(其中可能有很多)。所以這比爲每個具體類型注入一個XFactory併爲它寫一個XFactoryImpl(我試圖避免的)更爲重要。

我希望我可以這樣做

injector.getInstance(new TypeLiteral<MyCheckedProvider<X>>() {}); 

injector.getCheckedProvider(cls, MyCheckedException.class); 

但似乎不支持此操作。

回答

1

您想在此處使用Key類,而不是TypeLiteral。那麼就沒有必要ProviderHolder

Injector injector = Guice.createInjector(module); 
MyCheckedProvider<X> provider = injector.getInstance(new Key<MyCheckedProvider<X>>(){}); 
try {... 
+0

當然,不知道爲什麼我沒有看到。謝謝!現在,如果我可以擺脫'XImplProvider',這將會很棒。 –