当构造函数的参数不可用时,PHP依赖注入

Kar*_*ite 8 php dependency-injection mongodb

我们刚刚开始齐心协力在项目中统一使用依赖注入,我遇到了一个问题.

我正在编写一个类来处理MongoDB查询.我传入一个MongoClient作为构造函数的依赖,没有问题.但是,如果在实例化时实例化对象所需的变量不可用,我该如何处理依赖?

特别是,我们有一个MongoCollection方法的包装器,findOne,如果你传入一个字符串,当前(在旧代码中)将该字符串转换为带有"new MongoId($ _ id)"的MongoId,并将其用于查找功能.

根据我对依赖注入的了解,使用"new MongoId"是一个坏主意,而且我已经知道它会使为字符串转换为MongoId的函数编写测试用例变得更加困难.

但是当MongoId类在构造函数上获取id字符串时,如何处理注入?

我唯一能想到的就是在类构造函数上传递一个闭包,它执行以下操作:

$getMongoId = function( $id ){
    return new MongoId( $id );
};
Run Code Online (Sandbox Code Playgroud)

class MyMongo
{
   function __construct( MongoClient $client, Closure $mongoIdGetter){...}
}
Run Code Online (Sandbox Code Playgroud)

[编辑修复此最后一部分]

但这是处理它的正确方法吗?当然,如果我们使用DiC,我们可以做到,但需要一个闭包构造函数似乎有点多.我只是在注入依赖关系时过于教条吗?我想在新课程中使用"new MongoId($ _ id)"可以轻松解决这个问题.

Sam*_*aye 1

但是,当实例化对象所需的变量在实例化时不可用时,如何处理依赖关系呢?

在你有机会自己处理之前,PHP 就会出现致命错误。如果您使用类型参数和/或不定义它们,默认情况下,null当该参数未传递给任何函数时,PHP 将出现致命错误。

根据我对依赖注入的了解,拥有“new MongoId”是一个坏主意,而且我已经知道这将使为将字符串转换为 MongoId 的函数编写测试用例变得更加困难。

会吗(在 PHPUnit 中)?

$this->assertInstanceOf('\MongoId', $getMongoId($id_string));
Run Code Online (Sandbox Code Playgroud)

但是,当 MongoId 类在构造函数中获取 id 字符串时,我该如何处理注入呢?

不知道你的意思,但你应该只测试MongoIds 处理的结果。

你的问题的最后一点让我有点松懈,我认为这是因为它不是真正的 PHP (即$__construct)。

我不确定为什么你需要将函数推入类中。我的意思是我最多的时候是:

function findById($id){
    if(!$id instanceof \MongoId) $id = new MongoId($id);
    return $this->getCollection()->findOne($id);
}
Run Code Online (Sandbox Code Playgroud)

除此之外,您不需要任何其他东西,也不需要测试构造函数,MongoId因为它已经过单元测试,您应该对您的公共 API 而不是其他人的公共 API 进行单元测试。