当我们通过 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] = ??? }
它将破坏现有客户,如果Service2.f2
不提供Service3
额外服务,他们将无法再使用。
通过注入(通过构造函数或设置器)进行 DI,这在 OOP 中很常见,我将c
仅用作Service2
. 它是如何构造的以及它的依赖项列表是什么,我不在乎。从这一点开始,任何新的依赖都Service2
将保持函数的签名c
不变。
它是如何以FP方式解决的?有选择吗?有没有办法注入新的依赖项,但以某种方式保护客户免受更改?