Using tenant specific facades | laravel-multitenancy | Spatie

 SPATIE

  Laravel Multitenancy
=======================

spatie.be/open-source

  [Docs](https://spatie.be/docs)  [Laravel-multitenancy](https://spatie.be/docs/laravel-multitenancy/v3)  Advanced-usage  Using tenant specific facades

 Version   v4   v3   v2   v1

 Other versions for crawler [v4](https://spatie.be/docs/laravel-multitenancy/v4) [v3](https://spatie.be/docs/laravel-multitenancy/v3) [v2](https://spatie.be/docs/laravel-multitenancy/v2) [v1](https://spatie.be/docs/laravel-multitenancy/v1)

- [ Introduction ](https://spatie.be/docs/laravel-multitenancy/v3/introduction)
- [ Support us ](https://spatie.be/docs/laravel-multitenancy/v3/support-us)
- [ Requirements ](https://spatie.be/docs/laravel-multitenancy/v3/requirements)
- [ Questions and issues ](https://spatie.be/docs/laravel-multitenancy/v3/questions-issues)
- [ Changelog ](https://spatie.be/docs/laravel-multitenancy/v3/changelog)
- [ ](https://spatie.be/docs/laravel-multitenancy/v3/installation-setup)

Installation
------------

- [ Base installation ](https://spatie.be/docs/laravel-multitenancy/v3/installation/base-installation)
- [ Using a single database ](https://spatie.be/docs/laravel-multitenancy/v3/installation/using-a-single-database)
- [ Using multiple databases ](https://spatie.be/docs/laravel-multitenancy/v3/installation/using-multiple-databases)
- [ Determining the current tenant ](https://spatie.be/docs/laravel-multitenancy/v3/installation/determining-current-tenant)

Basic usage
-----------

- [ Automatically determining the current tenant ](https://spatie.be/docs/laravel-multitenancy/v3/basic-usage/automatically-determining-the-current-tenant)
- [ Working with the current tenant ](https://spatie.be/docs/laravel-multitenancy/v3/basic-usage/working-with-the-current-tenant)
- [ Making queues tenant aware ](https://spatie.be/docs/laravel-multitenancy/v3/basic-usage/making-queues-tenant-aware)

Advanced usage
--------------

- [ Ensuring a current tenant has been set ](https://spatie.be/docs/laravel-multitenancy/v3/advanced-usage/ensuring-a-current-tenant-has-been-set)
- [ Looping over a collection of tenants ](https://spatie.be/docs/laravel-multitenancy/v3/advanced-usage/looping-over-a-collection-of-tenants)
- [ Making Artisan command tenant aware ](https://spatie.be/docs/laravel-multitenancy/v3/advanced-usage/making-artisan-commands-tenant-aware)
- [ Using a custom tenant model ](https://spatie.be/docs/laravel-multitenancy/v3/advanced-usage/using-a-custom-tenant-model)
- [ Listening for events ](https://spatie.be/docs/laravel-multitenancy/v3/advanced-usage/listening-for-events)
- [ Using tenant specific facades ](https://spatie.be/docs/laravel-multitenancy/v3/advanced-usage/using-tenant-specific-facades)
- [ Executing code for tenants and landlords ](https://spatie.be/docs/laravel-multitenancy/v3/advanced-usage/executing-code-for-tenants-and-landlords)

Using tasks to prepare the environment
--------------------------------------

- [ Overview ](https://spatie.be/docs/laravel-multitenancy/v3/using-tasks-to-prepare-the-environment/overview)
- [ Creating your own task ](https://spatie.be/docs/laravel-multitenancy/v3/using-tasks-to-prepare-the-environment/creating-your-own-task)
- [ Switching databases ](https://spatie.be/docs/laravel-multitenancy/v3/using-tasks-to-prepare-the-environment/switching-databases)
- [ Switching route cache paths ](https://spatie.be/docs/laravel-multitenancy/v3/using-tasks-to-prepare-the-environment/switching-route-cache-paths)
- [ Prefixing cache ](https://spatie.be/docs/laravel-multitenancy/v3/using-tasks-to-prepare-the-environment/prefixing-cache)

      You are viewing the documentation for **an older version** of this package. You can check the version you are using with the following command:

 `                                    composer show spatie/laravel-multitenancy                                                                                                                                                                                                                                    `

Using tenant specific facades
=============================

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\Models\Tenant;
use Spatie\Multitenancy\Tasks\SwitchTenantTask;

class ClearFacadeInstancesTask implements SwitchTenantTask
{
    public function makeCurrent(Tenant $tenant): void
    {
        // tenant is already current
    }

    public function forgetCurrent(): void
    {
        $facadeClasses = [
            // array containing class names of faces you wish to clear
        ];

        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](https://github.com/spatie/laravel-multitenancy/discussions/240#discussion-3354768)) which will loop through all defined classes.

```
namespace App\Tenancy\SwitchTasks;

use Illuminate\Support\Facades\Facade;
use Illuminate\Support\Str;
use Spatie\Multitenancy\Models\Tenant;
use Spatie\Multitenancy\Tasks\SwitchTenantTask;

class ClearFacadeInstancesTask implements SwitchTenantTask
{
    public function makeCurrent(Tenant $tenant): void
    {
        // tenant is already current
    }

    public function forgetCurrent(): void
    {
        $this->clearFacadeInstancesInTheAppNamespace();
    }

    protected function clearFacadeInstancesInTheAppNamespace(): void
    {
        // Discovers all facades in the App namespace and clears their resolved instance:
        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()
            ));
    }
}
```
