VOOZH about

URL: https://deepwiki.com/hypervel/support/3.2-facade-system

⇱ Facade System | hypervel/support | DeepWiki


Loading...
Menu

Facade System

Purpose and Scope

The Facade System provides a static interface layer for accessing services registered in the dependency injection container. Facades allow application code to call methods on underlying services using a clean, expressive static syntax while maintaining testability and dependency injection principles. This document covers the base Facade class implementation, the service resolution mechanism, instance lifecycle management, and comprehensive testing capabilities including spying, mocking, and swapping.

For information about specific facade implementations (Request, Response, DB, etc.), see their respective sections in the HTTP Layer (4), View Layer (5), and Data Persistence Layer (6). For the service container and dependency injection concepts, see Service Provider System (3.3).


Base Facade Pattern

All facades extend the abstract Facade class located at src/Facades/Facade.php15 which implements the core resolution and proxying logic. Concrete facade classes must implement the getFacadeAccessor() method to specify which service they represent.

Facade Resolution Flow


Sources: src/Facades/Facade.php144-192

The __callStatic Magic Method

The __callStatic() method at src/Facades/Facade.php144-153 intercepts all static method calls on facade classes. It resolves the underlying service instance via getFacadeRoot() and forwards the method call:

StepMethodPurpose
1__callStatic($method, $args)Intercept static call
2getFacadeRoot()Get resolved service instance
3$instance->{$method}(...$args)Forward call to instance

If no facade root is set, a RuntimeException is thrown at src/Facades/Facade.php149

Sources: src/Facades/Facade.php144-153

The getFacadeAccessor Method

Concrete facade classes must implement getFacadeAccessor() to return the service container binding identifier. The base implementation at src/Facades/Facade.php260-263 throws a RuntimeException if not overridden.

Example Facade Structure


Sources: src/Facades/Facade.php15-264


Facade Resolution Process

Facade resolution occurs through the resolveFacadeInstance() method at src/Facades/Facade.php177-192 which implements a three-tier resolution strategy:

Resolution Strategy

PrioritySourceImplementation
1Direct objectIf accessor is an object, return it immediately
2Cached instanceCheck $resolvedInstance[$name] static cache
3Container resolutionResolve from ApplicationContext::getContainer()->get($name)

Resolution Algorithm


Sources: src/Facades/Facade.php177-192

Container Integration

Facades integrate with Hyperf's dependency injection container through the ApplicationContext class. The container is accessed at src/Facades/Facade.php27-188 for service resolution, instance registration, and lifecycle callbacks.

Key Container Operations:

Sources: src/Facades/Facade.php27-188


Facade Lifecycle

Facade instances are managed through a static $resolvedInstance array at src/Facades/Facade.php20 providing caching and lifecycle control.

Lifecycle Management Methods


Sources: src/Facades/Facade.php20-208

Instance Caching

Once resolved, instances are cached in the $resolvedInstance array indexed by the facade accessor name. Subsequent calls reuse the cached instance, avoiding repeated container resolution. The cache check occurs at src/Facades/Facade.php183-185 before container access.

Sources: src/Facades/Facade.php183-188

The swap() Method

The swap() method at src/Facades/Facade.php131-136 allows hot-swapping the underlying service instance. This is used extensively in testing but can also be used in production for dynamic service replacement:


Sources: src/Facades/Facade.php131-136

Clearing Resolved Instances

The facade system provides two methods for clearing cached instances:

MethodScopeImplementation
clearResolvedInstance($name)Single facadeUnsets $resolvedInstance[$name]
clearResolvedInstances()All facadesResets $resolvedInstance = []

These methods at src/Facades/Facade.php196-208 are typically used in testing to ensure clean state between tests.

Sources: src/Facades/Facade.php196-208

The resolved() Callback

The resolved() method at src/Facades/Facade.php25-37 registers callbacks that execute when a facade's underlying service is resolved. If the service is already resolved, the callback executes immediately. Otherwise, it registers with the container's afterResolving() hook:

Sources: src/Facades/Facade.php25-37


Testing Capabilities

The facade system provides comprehensive testing utilities through integration with the Mockery library. These methods enable spying, partial mocking, expectation setting, and instance swapping.

Testing Method Overview


Sources: src/Facades/Facade.php42-164

The spy() Method

The spy() method at src/Facades/Facade.php42-53 creates a Mockery spy that records method calls without altering behavior. It automatically swaps the spy into the facade using the swap() method:

Spy Creation Flow:

  1. Check if facade is already mocked via isMock() src/Facades/Facade.php44
  2. Get mockable class via getMockableClass() src/Facades/Facade.php48
  3. Create Mockery spy with or without class src/Facades/Facade.php50
  4. Swap spy into facade src/Facades/Facade.php51
  5. Return spy instance for assertions

Sources: src/Facades/Facade.php42-53

The partialMock() Method

The partialMock() method at src/Facades/Facade.php58-67 creates a partial mock that only mocks specified methods, allowing real methods to execute normally:


Sources: src/Facades/Facade.php58-67

The shouldReceive() Method

The shouldReceive() method at src/Facades/Facade.php72-81 enables Mockery expectation syntax for facades. Like partialMock(), it reuses existing mocks or creates new ones:

Implementation Details:

Sources: src/Facades/Facade.php72-81

Mock Creation Infrastructure

The facade system uses several protected methods to create and configure mocks:

MethodPurposeKey Logic
createFreshMockInstance()Create and swap new mockCalls createMock(), then swap(), enables protected method mocking
createMock()Create Mockery mockGets mockable class, creates typed or untyped mock
getMockableClass()Get class name to mockRetrieves class from getFacadeRoot()
isMock()Check if instance is mockChecks if $resolvedInstance[$name] is LegacyMockInterface
isFake()Check if instance is fakeChecks if $resolvedInstance[$name] is Fake

Sources: src/Facades/Facade.php86-164

Testing Pattern Example


Sources: src/Facades/Facade.php72-153


Default Facade Aliases

The facade system provides a comprehensive list of default facade aliases through the defaultAliases() method at src/Facades/Facade.php213-253 This static method returns a Collection containing 37 facade mappings:

Facade Categories

CategoryFacadesExample Classes
CoreApp, Artisan, Config, EnvironmentApp::class, Config::class
HTTPRequest, Response, Cookie, Route, URLRequest::class, Route::class
DataDB, Cache, Redis, QueueDB::class, Cache::class
ViewView, BladeView::class, Blade::class
CommunicationEvent, Broadcast, Http, Mail, NotificationEvent::class, Http::class
SecurityAuth, Gate, Hash, Crypt, JWTAuth::class, Gate::class
InfrastructureBus, Log, File, Storage, Process, ScheduleBus::class, Log::class
UtilitiesDate, Validator, RateLimiter, SessionDate::class, Validator::class

These aliases enable shorter, more expressive syntax (e.g., DB instead of Hypervel\Support\Facades\DB) when registered in the application's class alias system.

Sources: src/Facades/Facade.php213-253


Integration with Reflection

While the facade system primarily relies on PHP's __callStatic magic method, the codebase includes reflection utilities in src/Reflector.php1-137 that can be used for advanced facade introspection and parameter type resolution. The Reflector class provides:

These utilities support scenarios where facades need to inspect method signatures or validate parameter types at runtime, particularly useful in advanced testing or dynamic method binding scenarios.

Sources: src/Reflector.php1-137