2016-12-06 8 views
1

のは、私はその後、私のアプリケーションで使用できるコンポーネントの多くを結合しThirPartyModuleサードパーティ製のモジュールを持っているとしましょう:Guice:サードパーティ製モジュールのバインディングをカスタマイズする方法は?

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

私はそのモジュールにいくつかのバインディングに使用する実装クラスを変更したい場合は、どのような最善のアプローチですか?

たとえば、のは、結合ThirPartyModule行いをしましょう:

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

と私はMyWidgetImplクラスのDefaultWidgeImplクラスを変更できるようにしたいです。私は、オーバーライドするモジュールを使用することができ、単にWidgetInterfaceキーを再バインドすることができます。しかし、どうすればThirPartyModuleがバインドするかたくさんその同じウィジェットの実装?私は彼らのそれぞれを再バインドする必要はありません!

私はそれに応じてすべてのコンポーネントを再バインドせずに、使用する実装クラスを指定できる最適なソリューションを見つけようとしています。

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

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

し、アプリケーションがgetWidgetImpClass()メソッドオーバーライドすることができます::

私はThirPartyModuleが最初にゲッター実装クラスのメソッド作成することができます推測

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キーを介して間接的に行くことで、あなただけの結合が1を上書きする必要があります。

+0

うわー、私は「オプションバインダー」も知らなかったことを認めなければなりません。本当に便利です...ありがとう! – electrotype

+0

シングルトンは '@Named(" default ")'とは関係がありません。 'CustomWidgetImpl'がシングルトンでなければならない場合、それを' @Singleton'でマークするか '.in(Singleton.class)'で行います。 –

+0

それにもかかわらず、あなたはおそらく '@Named(" default ")'なしで行うことができます。 '{CoolWidget、AwesomeWidget} - > WidgetInterface - > DefaultWidgetImpl'のようになります。 –

関連する問題