Php 解析抽象类';在Laravel中通过依赖注入实现依赖
我在使用存储库模式时遇到了这个问题。目前,我使用一个接口和一个自定义类来实现它,然后在控制器的构造中键入hint,由于Laravel,它将自动递归地解决存储库的依赖关系 我也在服务提供商中这样做:Php 解析抽象类';在Laravel中通过依赖注入实现依赖,php,dependency-injection,laravel-5.2,abstract-class,Php,Dependency Injection,Laravel 5.2,Abstract Class,我在使用存储库模式时遇到了这个问题。目前,我使用一个接口和一个自定义类来实现它,然后在控制器的构造中键入hint,由于Laravel,它将自动递归地解决存储库的依赖关系 我也在服务提供商中这样做: $this->app->bind(path/to/repoInterface,path/to/implementationClass) 然而,由于我对这些存储库的编码方式,为了避免代码重复,我创建了一个抽象类,该类对所有这些存储库都有一个通用方法。这类课程如下: abstract cla
$this->app->bind(path/to/repoInterface,path/to/implementationClass)
然而,由于我对这些存储库的编码方式,为了避免代码重复,我创建了一个抽象类,该类对所有这些存储库都有一个通用方法。这类课程如下:
abstract class CommonRepo{
public function __construct(SomeModelClass model){}
public function commonMethod(){//Code here}
我的存储库具有以下结构:
public class ExampleRepository extends CommonRepo implements ExampleRepositoryI{
public function __construct(){
parent::__construct();
}
}
Laravel不喜欢这样,因此它给出了以下错误:
Argument 1 passed to path/to/repo/CommonRepo::__construct() must be an instance of path/to/model/SomeModelClass, none given, called in...
因此,显然不是解决CommonRepo类的依赖关系,而是解决了对普通存储库的依赖关系
如果可能的话,我想使用类型暗示(Laravel方式),而不必做任何与新操作符相关的事情
那么,我如何解决该类的依赖关系呢?
PD:使用Laravel 5.2调用父构造函数就像调用普通函数一样,不涉及依赖项解析器,因此您应该执行以下两种可能性之一:
public class ExampleRepository extends CommonRepo implements ExampleRepositoryI
{
public function __construct(SomeModelClass $model){
parent::__construct($model);
}
}
或
问得好。我做了一些修补,虽然我不知道这是否是你要找的。但是,您可以动态创建存储库类所需的雄辩模型的实例 假设您的
User
模型类存储在app\Models\User.php
中:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
//
}
现在,假设您想要为用户
模型创建一个存储库,并且该用户的存储库必须实现以下接口:app\Repositories\UserRepositoryInterface.php
<?php
namespace App\Repositories;
interface UserRepositoryInterface
{
public function getByEmail($email);
}
通过这种方式,您可以将UserRepositoryInterface
绑定到它的实现,如下所示:
$this->app->bind(\App\Repositories\UserRepositoryInterface::class, \App\Repositories\UserRepository::class);
最后,您可以将UserRepositoryInterface
自由注入控制器的构造函数或方法。您还可以通过如下服务容器解决此问题:
$userRepository = App::make(App\Repositories\UserRepositoryInterface::class);
$userRepository->getByEmail('john@example.com');
当然,这种方法有一个陷阱。repository类应该从关联的模型开始,因此InvoiceRepository.php
专用于Invoice.php
模型类
希望这有帮助 这可能会有帮助。您可以侦听对象何时解析和设置属性
$this->app->resolving(CommonRepo::class, function ($object, $app) {
// Called when container resolves object of any type...
$object->commonObject = app(CommonObject::class);
});
文档:谢谢您的时间,但这正是我想要避免的,因为我必须编写父:构造(App::make(SomeModelClass::class));在每个存储库中(目前我有6个从该公共父级扩展而来),因此如果我必须在该ComonRepo中添加/删除/修改依赖项,这会变得很糟糕。你可以从中得到启发,或者如果除了调用父构造函数没有其他事情要做的话,可以从ExampleRepository类中删除构造函数。@MateuszDrost我没有键入它,但还有更多的事情要做。每个存储库都有自己的依赖项(通常只是雄辩的模型,因为我不喜欢滥用facades)。尽管这并不完全是我想要的,但我肯定能在未来找到它的用途,因为我不断发现自己注入了模型,有时它与回购协议的名称匹配,所以它很好。但是,您不应该缓存getModel()方法吗?比如在构造函数中调用它?
$this->app->bind(\App\Repositories\UserRepositoryInterface::class, \App\Repositories\UserRepository::class);
$userRepository = App::make(App\Repositories\UserRepositoryInterface::class);
$userRepository->getByEmail('john@example.com');
$this->app->resolving(CommonRepo::class, function ($object, $app) {
// Called when container resolves object of any type...
$object->commonObject = app(CommonObject::class);
});