Facades behave like singletons. They only resolve once, and each use of the facade is against the same instance. For multitenancy, this may be problematic if the underlying instance behind a service, is built using tenant specific configuration.
If you only have a couple of tenant specific facade, we recommend only clearing them when switching a tenant. Here's a task that you could use for this.
namespace App\Tenancy\SwitchTasks;
use Illuminate\Support\Facades\Facade;
use Illuminate\Support\Str;
use Spatie\Multitenancy\Contracts\IsTenant;
use Spatie\Multitenancy\Tasks\SwitchTenantTask;
class ClearFacadeInstancesTask implements SwitchTenantTask
{
public function makeCurrent(IsTenant $tenant): void
{
}
public function forgetCurrent(): void
{
$facadeClasses = [
];
collect($facadeClasses)
->each(
fn (string $facade) => $facade::clearResolvedInstance($facade::getFacadeAccessor);
);
}
}
Should you want to clear out all defined facades, you can use this code (provided by Adrian Brown) which will loop through all defined classes.
namespace App\Tenancy\SwitchTasks;
use Illuminate\Support\Facades\Facade;
use Illuminate\Support\Str;
use Spatie\Multitenancy\Contracts\IsTenant;
use Spatie\Multitenancy\Tasks\SwitchTenantTask;
class ClearFacadeInstancesTask implements SwitchTenantTask
{
public function makeCurrent(IsTenant $tenant): void
{
}
public function forgetCurrent(): void
{
$this->clearFacadeInstancesInTheAppNamespace();
}
protected function clearFacadeInstancesInTheAppNamespace(): void
{
collect(get_declared_classes())
->filter(fn ($className) => is_subclass_of($className, Facade::class))
->filter(fn ($className) => Str::startsWith($className, 'App') || Str::startsWith($className, 'Facades\\App'))
->each(fn ($className) => $className::clearResolvedInstance(
$className::getFacadeAccessor()
));
}
}