2017-05-29 3 views
0

アダプタを名前付き引数にバインドするGuiceモジュールを実装したいのですが、このアダプタを作成するには注入された引数も必要とする別のクラスをインスタンス化する必要があります。ここでGuiceはクラスとそのアダプタをバインドします

はScalaの例である:

trait Service 

class UserService @Inject()(@Named(value = "foo") foo: String) extends Service 

trait Adapter 

class AdapterImpl(service: Service) extends Adapter 

class AdapterRef(val adapter: Adapter) 


class Module extends AbstractModule { 
    override def configure(): Unit = { 
    val fooValue = "bar" 

    bind(classOf[String]) 
     .annotatedWith(Names.named("foo")) 
     .toInstance(fooValue) 


    val userService = new UserService(fooValue)  //It should be instantiated by Guice somehow 

    bind(classOf[AdapterRef]) 
     .annotatedWith(Names.named("userService")) 
     .toInstance(new AdapterRef(new AdapterImpl(userService))) //Thats kinda ok 
    } 
} 

誰かが正しい方向に私を指すことができますか?

はあなたがバインディングを削除することができますあなたのモジュール内Provides方法を使用することができます

ガボール

+0

エラーは何ですか? – rethab

+0

エラーはありません。システムにすべての依存関係を注入したいので、 "val userService = new UserService(fooValue)"という行を置き換えることができる解決策が必要です。 –

+0

インジェクタを作成し、モジュールに渡します。その後、インジェクタからインスタンスを取得します。ドキュメント:https://google.github.io/guice/api-docs/3.0/javadoc/com/google/inject/Guice.html – rethab

答えて

0

、ありがとうございます。これはScalaでの私の最善の努力ですので、構文が間違っている場合は教えてください。

@Provides() @Singleton() def provideAdapterRef(service: Service): AdapterRef = { 
    return new AdapterRef(new AdapterImpl(service)) 
} 

toInstanceのあなたの例の使用を模倣するシングルトンを使用します。常に同じインスタンスを提供する必要がない場合は、スコープを削除し、毎回新しいスコープを作成することをお勧めします。

別の解決策は、Providerを使用することです。これには、モジュール内のバインディングの変更されたバージョンを保持し、余分なクラスを作成する必要がありますが、プロバイダがより複雑な場合は、よりクリーンなソリューションになる可能性があります。

//Can inject UserService as well, or provide annotations to configure which 
//implementation of Service you get if you have more than one. 
class UserServiceProvider @Inject()(service: Service) extends Provider[AdapterRef] { 
    override def get(): AdapterRef { 
     return new AdapterRef(new AdapterImpl(service)) 
    } 
} 

は、その後、あなたはここにあなたの toInstance動作を複製する in(Singleton)の使用を注意してください、あなたは

bind(classOf[AdapterRef]) 
    .annotatedWith(Names.named("userService")) 
    .toProvider(classOf[UserServiceProvider]) 
    .in(classOf[Singleton]) 

へのモジュールに結合変更することができます。

関連する問題