Scala - 为工厂实例化的 Child 类 提供不同的依赖关系

Scala - Supplying Different Dependencies to Child Classes Instantiated by Factory

我正在尝试编写一个作业执行模块,它使用工厂来提供执行作业的逻辑,具体取决于作业的类型。

我的难题是如何为特定实现提供不同依赖性,同时保持实例化的通用签名。

以下是删节代码。

基地 class 工厂:

abstract class JobExecution(job: Job, jobService: JobService) {
    def execute: Unit
}

object JobExecution {
  val registry: Map[Long, (Job, JobService) => JobExecution] = Map(
    1L -> ((j: Job, s: JobService) =>
      new SomeJobExecImpl(j, s).asInstanceOf[JobExecution])
  )

  def apply(job: Job, service: JobService): JobExecution = registry(job.jobTypeId)(job, service)
}

传入的作业是这样执行的:

// Note that here I have the services in scope that I would like to supply to the job execution implementation.

JobExecution(someJob, jobService).execute

我需要这样的实现:

class SomeJobExecImpl(job: Job, jobService: JobService, otherService: OtherService)
  extends JobExecution(job, jobService) {
    def execute: Unit = ???
}

或者也许:

class SomeJobExecImpl(job: Job, jobService: JobService)
                     (implicit otherService: OtherService)
  extends JobExecution(job, jobService) {
    def execute: Unit = ???
}

除了一些臭味 work-arounds。

我无法想出解决方案

在保留基本模式的同时,是否有令人信服的方法可以做到这一点,或者是否需要进行大规模更改?

请注意,我没有使用 DI 库。

在对现有结构进行最小更改的情况下,一种选择是在 ServiceRegistry 中列出所有服务,例如:

trait ServiceRegistry {
  implicit val jobService: JobService
  implicit val otherService: OtherService
  ...
}

然后更改您的 JobExecution 注册表:

...
object JobExecution {
  val registry: Map[Long, (Job, ServiceRegistry) => JobExecution] = Map(
    1L -> ((j: Job, r: ServiceRegistry) =>
      import r._
      new SomeJobExecImpl(j, r.jobService).asInstanceOf[JobExecution])
  )

  def apply(job: Job, serviceReg: ServiceRegistry): JobExecution = 
    registry(job.jobTypeId)(job, serviceReg)
}

JobExecution 实施需要额外服务时:

class SomeJobExecImpl(job: Job, jobService: JobService)
                     (implicit otherService: OtherService)
  extends JobExecution(job, jobService) {
    def execute: Unit = ???
}