2017-03-16 12 views
0

Dagger 2を使用して、私はプレゼンターに提供するドメインオブジェクトを持っています。そのドメインオブジェクトはリポジトリに依存します。そのリポジトリには2つの実装がありますが、どちらも同じインタフェースを実装しています。私は、「Demo Mode」オプションを選択したユーザに基づいて、実行時にリポジトリの2つの実装をスワップするために何とかして段帳をセットアップできる必要があります。Dagger提供の依存関係に対するランタイムスワップの実装

だから私は持っている次のドメインオブジェクト:

public class SomeAwesomeBusinessLogic { 

    Repository repository; 

    @Inject 
    public SomeAwesomeBusinessLogic(Repository repository) { 
     this.repository = repository; 
    } 
    //awesome stuff goin down 
} 

そして、2つのリポジトリ:この作業を取得するために私のモジュールおよびコンポーネントを構築する方法について

public RemoteRepository implements Repository { 

    @Inject 
    public RemoteRepository() { 
     //setup 
    } 
} 

public DemoRepository implements Repository { 

    @Inject 
    public DemoRepository() { 
     //setup 
    } 
} 

任意のアイデア?

答えて

0

私の頭にはいくつかのアイデアがあります。いつ、どのように交換したいかによって、 1つの可能性は、構成を使用してモジュールをインスタンス化することです。単純なブール値にすることができます:

@Module 
public class RepositoryModule { 
    private final boolean isDemo; 

    public RepositoryModule(boolean isDemo) { 
    this.isDemo = isDemo; 
    } 

    @Provides 
    public Repository providesRepository() { 
    return isDemo? new DemoRepository() : new RemoteRepository(); 
    } 
    // Other providers 
} 

私はこのアプローチのファンではありませんが、ユースケースに合っています。私はそれが非常に限定的であり、容易な保守性を考慮していないと信じています。私はおそらく、工場を使用し、レポ自体の代わりに工場を提供することを選択します。

public interface RepositoryFactory { 
    Repository getRepository(Configuration configuration); 
} 

public class RepositoryFactoryImpl implements RepositoryFactory { 

    @Inject 
    public RepositoryFactoryImpl() {} 

    // The implementation 
} 

@Module 
public class RepositoryModule { 
    @Provides 
    public RepositoryFactory providesRepositoryFactory(
      RepositoryFactoryImpl factory) { 
    return factory; 
    } 
    // Other providers 
} 

Configurationあなたのレポを設定するには、いくつかの属性を指定することができ、簡単なPOJOだろう。例えば言う:

public class Configuration { 
    private final boolean isDemo; 
    // all the POJO stuff you need 
} 

あなたは、あなたのドメインオブジェクトは工場に依存することができます:

public class SomeAwesomeBusinessLogic { 

    private final RepositoryFactory repositoryFactory; 

    @Inject 
    public SomeAwesomeBusinessLogic(
       RepositoryFactory repositoryFactory) { 
     this.repositoryFactory = repositoryFactory; 
    } 
    //awesome stuff going down 
} 

あなたは、あなたのビジネスロジックにrepositoryFactory.getRepository(new Configuration(true/false));を行うことができます。

私は、新しいタイプのreposに拡張する方が簡単なので、この方法をお勧めします。また、ファクトリロジックが正しいかどうかをテストすることもできます。誰も通常、短剣モジュールをテストする人はいません。そのため、私は最初のアプローチに熱心ではありません。

もう1つの良い点は、異なるConfigurationオブジェクトを工場に提供することによって、アプリケーションの設定を変更してデモレポに突然変更する可能性がある場合に、同じモジュールインスタンスを維持できることです。

3番目の可能性はProducersです。しかし、これは本当にあなたのユースケースと、このランタイム依存関係の交換をどのように処理するかによって異なります。私はこのアプローチがかなり良いと思っていますが、それはちょっと残忍かもしれません。

希望すると便利です。

関連する問題