OG Framework
OG Framework Documentação
Voltar para Documentação

Arquitetura

Container de Dependências

O Container é o coração do framework — responsável por gerenciar dependências, instanciar classes automaticamente e servir como ponte entre o código moderno e o legado.

O que é Dependency Injection?

Dependency Injection (DI) é um padrão onde as dependências de uma classe são "injetadas" em vez de criadas internamente. Isso torna o código testável e desacoplado:

// ❌ SEM DI — dependência acoplada
class UserService {
    public function __construct() {
        $this->database = new DatabaseConnection(); // Problema!
    }
}

// ✅ COM DI — dependência injetada
class UserService {
    public function __construct(DatabaseConnection $database) {
        $this->database = $database; // Flexível e testável
    }
}

Usando o Container

O helper app() é a forma principal de acessar o container:

// 1. OBTER o container
$container = app();

// 2. RESOLVER um serviço registrado
$cache = app('cache');
$database = app('database');

// 3. VERIFICAR se existe antes de usar
if (app()->has('database')) {
    $db = app('database');
}

// 4. RESOLVER com parâmetros
$service = app()->make(MyService::class, [
    'config' => $minhaConfig
]);

Serviços Disponíveis via app()

app('database')
app('cache')
app('auth')
app('user')
app('session')
app('router')
app('email')
app('hooks')

Auto-Wiring

O container usa reflection para resolver dependências via type-hints automaticamente:

use Og\Modules\Common\Queue\Contracts\QueueManagerInterface;
use Og\Modules\Common\Cache\Cache;

class ReportGenerator
{
    // O container injeta TUDO automaticamente!
    public function __construct(
        private QueueManagerInterface $queue,  // Resolvido via DI
        private Cache $cache                    // Resolvido via DI
    ) {}

    public function generate(int $reportId): void
    {
        // Usar cache
        if ($this->cache->has("report:{$reportId}")) {
            return $this->cache->get("report:{$reportId}");
        }

        // Enfileirar job
        $this->queue->push(new GenerateReportJob($reportId));
    }
}

// Uso — o container faz a mágica:
$generator = app(ReportGenerator::class);  // Tudo injetado!

make() vs get()

get($id)

Obtém serviço registrado. Lança exceção se não existir.

$cache = app()->get('cache');
$db = app()->get('database');

make($class, $params)

Instancia classe com auto-wiring. Aceita parâmetros extras.

$svc = app()->make(MyService::class);
$svc = app()->make(MyService::class, [
    'config' => $cfg
]);

Bridge com Legacy

O GlobalServiceProvider expõe variáveis globais ($u, $a, $s, etc.) via container. Assim você pode acessar tanto via $GLOBALS['u'] quanto via app('user') — facilitando a migração gradual.

// Código legacy
global $u;
if ($u->checkPriv('stocks:artigos')) {
    // ...
}

// Código moderno (equivalente!)
$user = app('user');
if ($user->checkPriv('stocks:artigos')) {
    // ...
}

// Ambos funcionam e estão sincronizados!
Container Global Legacy Classe
app('database') $GLOBALS['db'] DatabaseConnector
app('user') $GLOBALS['u'] User
app('app') $GLOBALS['a'] Aplication
app('session') $GLOBALS['s'] Session
app('email') $GLOBALS['mail'] Email

Próximo: Veja Service Providers para aprender como registrar serviços no container usando singleton(), bind(), e instance().