如何在Laravel Livewire中实施依赖注入
#编程 #php #laravel #livewire

我喜欢在代码中使用依赖项注入(DI)。它可以帮助我保持代码清洁并减少代码耦合。

什么是依赖注射

依赖注入是一种设计模式,可以通过删除创建对象及其依赖关系与使用它们的类的责任来分开关注点。相反,这些依赖项是由第三方或容器提供或注入类的。

这是PHP中的一个示例:

class UserService {
    private $userRepository;

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

    public function getUsers() {
        return $this->userRepository->findAll();
    }
}

class UserRepository {
    public function findAll() {
        // fetch users from the database
    }
}

在此示例中,UserService需要一个UserRepository对象来从数据库中获取用户。我们没有在UserService内部创建UserRepository对象,而是通过构造函数注入它。这可以更好地分离关注点并使UserService更加灵活,因为我们可以轻松地交换UserRepository实现而无需更改UserService代码。您可以在Laravel in documentation中阅读有关其工作原理的更多信息。

如何将DI与Livewire一起使用

当我们使用LiveWire组件时,我们可以使用其中的__construct方法,因为LiveWire需要$id用于组件。

我开始研究并找到了这个thread on GitHub。一些开发人员建议使用这样的mount()方法:

use Livewire\Component;
use Psr\Log\LoggerInterface;

class Foo extends Component
{
    protected LoggerInterface $logger;

    public function mount(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    public function render()
    {
        $this->logger->info('component rendered');
        return view('livewire.foo');
    }

    public function action()
    {
        $this->logger->info('action triggered');
    }
}

mount() di的问题是在某些情况下它不起作用。例如,当您单击按钮并致电action()时,您的$this->logger将为空。这是因为用户与组件交互时未调用mount()方法。

对我们来说,好消息是在version 2.6 of Livewire开发人员中添加了boot() Hook。每次您使用组件时,都会调用此钩子。这是您可以在LiveWire组件中使用DI的方法:

class YourComponent extends Livewire\Component
{
    private SomeService $someService;
    private OneMoreService $oneMoreService;

    public function boot(
        SomeService $someService,
        OneMoreService $oneMoreService
    )
    {
        $this->someService = $someService;
        $this->oneMoreService = $oneMoreService;
    }
}