我有一些问题,并且很少误解Laravel SP(ServiceProvider)。我有抽象类Repository和她的接口:
abstract class Repository implements RepositoryInterface {
private $model;
private $parser;
public function __construct() {
$this->model = new $this->model_name();
} }
interface RepositoryInterface {
public function create(array $attributes);
public function update($id, array $attributes);
public function delete($id);
public function all();
public function find($id);
public function filter(array $parameters, $query=null);
public function query(array $parameters, $query=null); }
和一些子UserRepository例如:
class UserRepository extends Repository implements UserRepositoryInterface {
protected $model_name = "App\Models\User";
public function __construct() {
parent::__construct();
}
public function activation($user_id) {
return "user";
}
public function deactivation($user_id) {
return "user";
} }
和简单的ModelParser类:
class ModelParser {
protected $parameters;
protected $model;
public function __construct($model) {
$this->model = $model;
} }
这项工作很好,但我会在我的带有参数ModelParser
的抽象Repository
构造中将$model
作为DI传递。我不知道。我该怎么办?
我这样用:
class UserController extends Controller {
private $repository;
public function __construct(UserRepository $repository) {
$this->repository = $repository;
} }
答案 0 :(得分:1)
因为ModelParser
需要$model
作为参数,所以它有点复杂。并且因为$model
可能会因其存储库而异,如果我们尝试使用Laravel service container binding来解决它,则会太复杂。
这是一种更简单的方法,我们可以让ModelParser
类的构造函数接收一个可选的$model
参数。然后我们可以添加一个额外的方法来设置这个$model
属性,如下所示:
namespace App\Models;
class ModelParser
{
protected $parameters;
protected $model;
// Make $model parameter optional by providing default value.
public function __construct($model = null) {
$this->model = $model;
}
// Add setter method for $model.
public function setModel($model)
{
$this->model = $model;
return $this;
}
}
现在您可以将ModelParser
注入抽象Repository
类。 Laravel将轻松解决此ModelParser
参数
namespace App\Models;
use App\Models\ModelParser;
use App\Models\RepositoryInterface;
abstract class Repository implements RepositoryInterface
{
private $model;
private $parser;
// Pass ModelParser instance to your constructor!
public function __construct(ModelParser $parser)
{
$this->model = new $this->model_name();
// Set the parser's model property.
$this->parser = $parser->setModel($this->model);
}
// Rest of your code.
}
如果您正在扩展抽象Repository
类,您仍然必须将此ModelParser
传递给构造函数,如下所示:
namespace App\Models;
use App\Models\ModelParser;
use App\Models\UserRepositoryInterface;
class UserRepository extends Repository implements UserRepositoryInterface
{
protected $model_name = "App\Models\User";
public function __construct(ModelParser $parser)
{
parent::__construct($parser);
}
}
实际上,如果您在课程实例化过程中没有计划传递其他参数或执行其他操作,则只需从__construct()
中移除UserRepository
方法并依赖其父级( abstract Repository
)。
希望这有帮助!