匕首 2 圆形依赖性

2022-09-02 22:40:33

在我正在处理的项目中,我有2个高度依赖的类:

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

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

这个想法是,在执行作品时,作品可以访问多个服务 - 其中之一是执行器本身,以便作品能够执行子作品。

正如人们所看到的,这里有一个循环依赖关系,但我发现很难打破。

主要问题是,WorkExecutor 实际上不需要在图构造时执行服务对象的实例,而只需要一个稍后使用的提供程序。可悲的是,Dagger不知道WorkExecutor不会从类的构造函数调用执行服务提供程序,因此它猜测执行服务依赖于WorkExecutor,反之亦然。

我发现的一个可能的解决方案是按以下方式定义模块和组件:

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();

但我不确定这是正确的行动方案 - 有没有更好的方法?


答案 1

我不怀疑OP会喜欢这样,因为你想要一种方法来使某些东西“错误”,工作“正确”。这不可能。每当您遇到循环依赖项时,“正确”的解决方案是重构以删除该依赖项。

在你的例子中,WorkExecutor是一个单例,所以它可能需要保持原样。然后,应修改执行服务简单,以删除对 WorkExecutor 的依赖关系。在不知道代码细节的情况下,不能说太多。但是,让执行服务独立于其“工作线程”会减少耦合,从长远来看可能是一件非常好的事情。


答案 2

为什么执行服务简单依赖于 WorkExecutor?

显示更多核心,执行服务听起来也像一个单例,为什么它相互依赖才能正常工作?

WorkExecutor听起来像是你可以传递给 as 的东西将被注入到其他地方,也许是使用 .ExecutionServiceWorkExecutorService

我不知道,显示更多的代码,也许这就是答案,它看起来很复杂。


推荐