Php 解析抽象类';在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

我在使用存储库模式时遇到了这个问题。目前,我使用一个接口和一个自定义类来实现它,然后在控制器的构造中键入hint,由于Laravel,它将自动递归地解决存储库的依赖关系

我也在服务提供商中这样做:

$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);
});