Comunicação entre Módulos
Como usar classes de outros módulos e declarar dependências no seu módulo.
Usar o Service de outro módulo
O container injeta automaticamente qualquer classe disponível. Para usar o UsuarioService no seu módulo, basta declarar no construtor:
<?php
namespace Src\Modules\Pedido\Services;
use Src\Modules\Usuario\Services\UsuarioService;
final class PedidoService
{
// Container injeta UsuarioService automaticamente
public function __construct(
private readonly PedidoRepository $repository,
private readonly UsuarioService $usuarioService
) {}
public function criar(array $data, string $userId): array
{
// Verifica se o usuário existe
$usuario = $this->usuarioService->buscarPorUuid($userId);
if (!$usuario) {
throw new \RuntimeException('Usuário não encontrado.');
}
return $this->repository->create($data + ['user_id' => $userId]);
}
}
Dependência opcional (módulo pode não existir)
Use ? para tornar a dependência opcional. O container injeta null se o módulo não estiver instalado:
use Src\Kernel\Contracts\EmailSenderInterface;
final class PedidoService
{
public function __construct(
private readonly PedidoRepository $repository,
private readonly ?EmailSenderInterface $email = null
) {}
public function criar(array $data): array
{
$pedido = $this->repository->create($data);
// Envia e-mail apenas se o serviço estiver disponível
$this->email?->sendCustom($data['email'], 'Pedido criado', '<p>Seu pedido foi criado!</p>');
return $pedido;
}
}
Declarar dependência de instalação (plugin.json)
Para impedir que seu módulo seja instalado sem que outro já esteja presente, crie plugin.json na raiz do módulo:
{
"name": "meu-vendor/pedido",
"description": "Módulo de pedidos",
"version": "1.0.0",
"requires": {
"modules": ["Usuario", "Produto"]
}
}
Regra de ouro
Nunca acesse a tabela de outro módulo diretamente via SQL. Sempre use o Service do módulo para obter dados. Isso garante que as regras de negócio sejam respeitadas.
Resumo
| Situação | Como fazer |
|---|---|
| Usar classes de outro módulo (obrigatório) | Type hint no construtor sem ? |
| Usar classes de outro módulo (opcional) | Type hint nullable: ?Tipo = null |
| Impedir instalação sem dependência | plugin.json com requires.modules |
| Verificar se módulo está ativo em runtime | is_dir('src/Modules/NomeModulo') |