18

私が取り組んでいるプロジェクトでは、互いに大きく依存している 2 つのクラスがあります。

@Singleton
class WorkExecutor {
    @Inject Provider<ExecutionServices> services;
    ...
    public void execute(Work w){
        w.execute(services.get());
        ...
    }
    ...
}

class ExecutionServicesImpl implements ExecutionServices {
    @Inject WorkExecutor executor;
    ...
}

アイデアは、作業を実行するときに、作業が複数のサービスにアクセスできるというものです。そのうちの 1 つはエグゼキュータ自体であるため、作業はサブ作業を実行できます。

ご覧のとおり、ここには循環依存関係がありますが、これを断ち切るのは非常に困難であることがわかりました。

主な問題は、 WorkExecutor が実際にはグラフ作成時に ExecutionServices オブジェクトのインスタンスを必要とせず、後で使用するプロバイダーのみを必要とすることです。悲しいことに、Dagger は、WorkExecutor がクラスのコンストラクターから ExecutionServices プロバイダーを呼び出さないことを認識していないため、ExecutionServices が WorkExecutor に依存していると推測し、その逆も同様です。

私が見つけた解決策の 1 つは、モジュールとコンポーネントを次のように定義することです。

interface DelayedProvider<T> extends Provider<T>{}

@Module
class AppModule {
    Provider<ExecutionServices> delayedProvider = null;

    @Provides DelayedProvider<ExecutionServices> provideDelayed() {
        return () -> delayedProvider.get();
    }

    @Provides @Named("late-binding-conf") Void latebindingConf(Provider<ExecutionServices> eager){
        this.delayedProvider = eager;
        return null; //notice we returning Void and not void
    }
}

@Component(modules=AppModule.class)
interface AppComponent {
    App app();
    @Named("late-binding-conf") Void configureLateBinding();
}

そして、元のクラスを次のように変更します。

@Singleton
class WorkExecutor {
    @Inject DelayedProvider<ExecutionServices> services;
    ...
    public void execute(Work w){
        w.execute(services.get());
        ...
    }
    ...
}

class ExecutionServicesImpl implements ExecutionServices {
    @Inject WorkExecutor executor;
    ...
}

そして、アプリを作成するには、次のことを行う必要があります。

AppComponent acomp = DaggerAppComponent.create();
App = acomp.app();
acomp.configureLateBinding();

しかし、これが適切な行動方針であるかどうかはわかりません。より良い方法はありますか?

4

3 に答える 3

0

ExecutionServicesImpl が WorkExecutor に依存するのはなぜですか?

コアをさらに表示します。ExecutionServices もシングルトンのように聞こえますが、正しく動作するために相互に依存しているのはなぜですか?

WorkExecutorに渡すことができるもののように聞こえますが、別の場所に注入される可能性がありExecutionServiceます。WorkExecutorService

わかりません。もっとコードを表示してください。おそらくそれが答えです。複雑に見えます。

于 2016-09-30T21:27:35.703 に答える