加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – JonasBonér的依赖注入策略似乎有限 – 但也许我不明白

发布时间:2020-12-16 18:51:06 所属栏目:安全 来源:网络整理
导读:我已多次阅读这篇文章: http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di.html 我想我明白了.然而,有一些我不太了解的东西. 看看他的UserService示例,我看到他设置了UserRepositoryComponent来封装UserRepository.但我不明白的
我已多次阅读这篇文章:

http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di.html

我想我明白了.然而,有一些我不太了解的东西.

看看他的UserService示例,我看到他设置了UserRepositoryComponent来封装UserRepository.但我不明白的是UserRepositoryComponent扮演两个角色的原因:它封装了UserRepository,还提供了对UserRepository对象的引用.

我试图想象如果我想创建依赖于两个UserRepository实例的服务,我将如何使用此模式.也许新服务的工作是将用户从“源”UserRepository复制到“目标”UserRepository.所以我想象的是这样的:

trait CopyUserServiceComponent {
  val source: UserRepositoryComponent
  val destination: UserRepositoryComponent
  class CopyUserServiceComponent { 
    ... 
  }
}

但这与原始模式不同.在这种情况下,我在组件本身中定义依赖项,而不是从其他组件继承它们.但在我看来,这是正确的方法:组件应该声明它们的依赖关系,而不是它们包含的服务的实例.

我在这里错过了什么?

解决方法

In this case I’m defining the dependencies in the component itself instead of inheriting them from some other component.

蛋糕模式不使用继承来声明依赖项.你在UserServiceComponent中看到任何“扩展”了吗?

But this seems to me to be the right way to do it: the components should declare their dependencies,not instances of their included services.

但这正是蛋糕模式的作用:声明依赖关系!也许如果示例包含def userRepositoryFactory = new UserRepository而不是val userRepository = new UserRepository,那会更清楚吗?

那么,让我们回到你的例子:

trait CopyUserServiceComponent {
  val source: UserRepositoryComponent
  val destination: UserRepositoryComponent
  class CopyUserServiceComponent { 
    ... 
  }
}

让我们看看我们不能做的事情:

trait CopyUserServiceComponent {
  // The module will need to see my internals!
  private val source: UserRepositoryComponent
  private val destination: UserRepositoryComponent
  class CopyUserServiceComponent { 
    ... 
  }
}

trait CopyBigUserServiceComponent extends CopyServiceComponent {
  // Any change in implementation will have to be reflected in the module!
  val tmp: UserRepositoryComponent
  ...
}

另一方面…

trait UserRepositoryComponent {
  val userRepositoryFactory: () => UserRepository

  class UserRepository {
    ...
  }
} 

trait CopyUserServiceComponent {
  self: UserRepositoryComponent =>
  // No problem here
  private val source: UserRepository = userRepositoryFactory()
  private val destination: UserRepository = userRepositoryFactory()
  class CopyUserServiceComponent { 
    ... 
  }
}

trait CopyBigUserServiceComponent extends CopyServiceComponent {
  self: UserRepositoryComponent =>
  // No problem here either
  val tmp: : UserRepository = userRepositoryFactory()
  ...
}

编辑

作为答案的补充,让我们考虑两个不同的需求:

>我需要很多UserRepository实例.

在这种情况下,您将以错误的级别应用模式.在Jonas的例子中,UserRepository处于工厂提供单例的级别.

因此,在这种情况下,您不会使用UserRepository和UserRepositoryComponent,而是使用UserRepositoryFactory和UserRepositoryFactoryComponent.

>我需要两个单独的UserRepository.

在这种情况下,只需执行以下操作:

trait UserRepositoryComponent {
  val sourceUserService: UserService
  val destinationUserService: UserService

  class UserService ...
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读