当我们通过Reader实现DI时,我们将依赖项作为方法签名的一部分。假设我们有以下代码(没有实现):
trait Service1 { def f1:Int = ??? }
trait Service2 { def f2:Reader[Service1, Int] = ??? }
type Env= (Service1, Service2)
def c:Reader[Env, Int] = ??? //use Service2.f2 here
现在,
f2
需要额外的服务来实现,比如:trait Service3
type Service2Env = (Service1, Service3)
//new dependecies on both:
trait Service2 { def f2:Reader[Service2Env, Int] = ??? }
它会破坏现有的客户端,他们不能再无需提供Service3
的情况下使用Service2.f2
。
通过注入依赖项(通过构造函数或设置器),这在OOP中很常见,我只会将Service2
作为c
的依赖项。如何构建它以及其依赖项列表,我不关心。从这一点出发,Service2
中的任何新依赖都将保持c
函数签名不变。
在FP方式中如何解决?是否有选项?是否有一种方法可以注入新的依赖项,但又能以某种方式保护客户免受更改的影响?