2016-12-06 76 views
1

比方說,我有一個結合許多組件,我可以在我的應用程序,然後使用一個ThirPartyModule第三方模塊:如果我想修改該模塊用於一些綁定實現類Guice:如何自定義第三方模塊的綁定?

Injector guice = Guice.createInjector(new MyAppModule(), new ThirPartyModule()); 

,什麼是最好的方法?

例如,假設ThirPartyModule執行該綁定:

bind(WidgetInterface.class).to(DefaultWidgeImpl.class).in(Scopes.SINGLETON); 

,我希望能夠改變DefaultWidgeImplMyWidgetImpl類。我知道我可以使用重寫模塊,只需重新綁定WidgetInterface鍵。但是,如果ThirPartyModule結合很多的使用同一widget實現東西呢?我可能不想要重新綁定他們每個人!

所以我試圖找到最好的解決方案,能夠指定要使用的實現類,而不必重新綁定所有組件取決於它。

我想ThirPartyModule可以先創建一個實現類getter方法:

bind(WidgetInterface.class).to(getWidgetImpClass()).in(Scopes.SINGLETON); 

protected Class<? extends WidgetInterface> getWidgetImpClass() { 
    return DefaultWidgeImpl.class; 
} 

然後應用程序可以覆蓋getWidgetImpClass()方法:

Injector guice = Guice.createInjector(new MyAppModule(), new ThirPartyModule() { 
    @Override 
    protected Class<? extends WidgetInterface> getWidgetImpClass() { 
     return MyWidgetImpl.class; 
    } 
}); 

我也不過關於通過實現類到模塊的構造函數:

Injector guice = Guice.createInjector(new MyAppModule(), new ThirPartyModule(MyWidgetImpl.class)); 

我想知道是否有可接受的模式來自定義此類第三方模塊?假設我可以要求模塊以特定的方式寫入,如果它有助於它們的定製。

回答

2

這是我會怎麼做:

public class ThirdPartyModule extends AbstractModule { 
    @Override 
    protected void configure() { 
     // CoolWidget -- 
     //    \ 
     //    > WidgetInterface -> DefaultWidgetImpl 
     //   /
     // AwesomeWidget 

     OptionalBinder.newOptionalBinder(binder(), WidgetInterface.class) 
       .setDefault() 
       .to(DefaultWidgetImpl.class); 

     bind(CoolWidget.class).to(WidgetInterface.class); 
     bind(AwesomeWidget.class).to(WidgetInterface.class); 
     // etc. 
    } 
} 

public class MyAppModule extends AbstractModule { 
    @Override 
    protected void configure() { 
     OptionalBinder.newOptionalBinder(binder(), WidgetInterface.class) 
       .setBinding() 
       .to(CustomWidgetImpl.class); 
    } 
} 

通過使所有綁定間接經過WidgetInterface鍵,你只需要越過一個結合。

+0

哇,我不得不承認,我甚至不知道'OptionalBinder',它確實很方便......謝謝! – electrotype

+0

我不認爲單身人士與'@Named(「default」)'有什麼關係。如果'CustomWidgetImpl'必須是單身,那麼用'@ Singleton'或者'.in(Singleton.class)'標記它。 –

+0

無論如何,你可能不需要'@Named(「default」)'。它只是'{CoolWidget,AwesomeWidget} - > WidgetInterface - > DefaultWidgetImpl'。 –