[Laravel]:如何将依赖项注入到由其他类(作业)扩展的抽象类中

时间:2018-09-03 11:21:46

标签: php laravel dependency-injection abstract solid-principles

我有一个Laravel项目,我在其中创建了一个抽象类,我的一些工作将使用该抽象类,因为它们都需要使用相同的方法来查找要继续处理的数据。

在Laravel中,作业的工作方式是构造函数获取触发作业的任何值,并在处理程序方法中注入依赖项,如下所示:

class SomeJob extends Job implements ShouldQueue
{
    public function __construct(array $someData, int $someMoreData)
    {
        $this->someData     = $someData;
        $this->someMoreData = $someMoreData;
    }

    public function handle()
    {
        // Do something...
    }
}


\Queue::pushOn(Queue::getDefaultQueue(), new SomeJob([1, 2, 3], 4));

这意味着我不能只将依赖项从扩展类的构造函数传递给抽象类。我看到的唯一解决方法是在抽象类上具有一个属性,然后在扩展类的处理程序方法中对其进行设置。

abstract class SomeAbstractClass extends Job implements ShouldQueue
{
    use InteractsWithQueue, SerializesModels;

    protected $configOne;
    protected $configTwo;
    protected $userRepository;

    public function __construct()
    {
        $this->configOne = config('someConfig.valueOne');
        $this->configTwo = config('someConfig.valueTwo');
    }

    public function doSomethingWithUserRepository()
    {
        return $this->userRepository->doSomething();
    }
}

class SomeClass extends SomeAbstractClass
{
    public function __construct(array $someData, int $someMoreData)
    {
        parent::__construct();

        $this->someData     = $someData;
        $this->someMoreData = $someMoreData;
    }

    public function handle(UserRepository $userRepository)
    {
        $this->userRepository = $userRepository;
    }
}

这可以按预期工作,但似乎不是正确的方法。即使可行,它似乎也有点骇人听闻。有办法解决这个问题吗?这一定是一个非常普遍的问题,同样在Laravel之外。

1 个答案:

答案 0 :(得分:1)

由于已定义的构造函数用于在Laravel中的作业中传递数据,因此在这种情况下,您必须将handle()视为“构造函数”方法。

因此请考虑以下示例:

<?php
abstract class SomeAbstractClass extends Job implements ShouldQueue
{
    use InteractsWithQueue, SerializesModels;

    protected $configOne;
    protected $configTwo;
    protected $userRepository;

    public function __construct()
    {
        $this->configOne = config('someConfig.valueOne');
        $this->configTwo = config('someConfig.valueTwo');
    }

    public function handle(UserRepository $userRepository)
    {
        $this->userRepository = $userRepository;
    }

    protected function doSomethingWithUserRepository()
    {
        return $this->userRepository->doSomething();
    }
}

class SomeClass extends SomeAbstractClass
{
    public function __construct(array $someData, int $someMoreData)
    {
        parent::__construct();
        $this->someData     = $someData;
        $this->someMoreData = $someMoreData;
    }

    public function handle(UserRepository $userRepository)
    {
        parent::handle($userRepository);

        // you can do whatever you liiike
        $this->doSomethingWithUserRepository();
    }
}