diff --git a/src/Environment.php b/src/Environment.php index 6de81300..aa055824 100644 --- a/src/Environment.php +++ b/src/Environment.php @@ -49,9 +49,7 @@ public function __construct(Application $app) if ((! $app->runningInConsole() || $app->runningUnitTests()) && $this->installed() && config('tenancy.hostname.auto-identification')) { - $this->identifyHostname(); - // Identifies the current hostname, sets the binding using the native resolving strategy. - $app->make(CurrentHostname::class); + $this->registerHostnameIdentification(); } } @@ -73,7 +71,23 @@ public function installed(): bool return $this->installed ?? $this->installed = $isInstalled(); } + /** + * Identify the hostname of the current request, and its tenant with it. + */ public function identifyHostname() + { + $this->registerHostnameIdentification(); + + $this->app->make(CurrentHostname::class); + } + + /** + * Arrange for the hostname to be identified, once something asks for it. + * + * Identification reads the current request, so it has to wait until there + * is one. Registering the binding is all that can be done up front. + */ + protected function registerHostnameIdentification() { $this->app->singleton(CurrentHostname::class, function () { /** @var Hostname $hostname */ diff --git a/src/Middleware/EagerIdentification.php b/src/Middleware/EagerIdentification.php index 02c4cae4..f5d7f03f 100644 --- a/src/Middleware/EagerIdentification.php +++ b/src/Middleware/EagerIdentification.php @@ -22,8 +22,13 @@ class EagerIdentification { public function handle(Request $request, Closure $next) { - if (config('tenancy.hostname.early-identification')) { - app(Environment::class); + if (config('tenancy.hostname.auto-identification') && + config('tenancy.hostname.early-identification')) { + // Identification reads the request, so it belongs here rather than + // in the environment's constructor. Asking again on every request + // is what keeps a long lived process from serving the tenant it + // identified for the first one. + app(Environment::class)->identifyHostname(); } return $next($request); diff --git a/src/Providers/TenancyProvider.php b/src/Providers/TenancyProvider.php index bf553beb..f67e3472 100644 --- a/src/Providers/TenancyProvider.php +++ b/src/Providers/TenancyProvider.php @@ -42,10 +42,8 @@ public function register() ); - $this->app->booted(function ($app) { - $app->singleton(Environment::class, function ($app) { - return new Environment($app); - }); + $this->app->singleton(Environment::class, function ($app) { + return new Environment($app); }); $this->app->singleton(Contracts\Repositories\HostnameRepository::class, Repositories\HostnameRepository::class); $this->app->singleton(Contracts\Repositories\WebsiteRepository::class, Repositories\WebsiteRepository::class); diff --git a/tests/Test.php b/tests/Test.php index 0611474d..03e54db1 100644 --- a/tests/Test.php +++ b/tests/Test.php @@ -14,6 +14,7 @@ namespace Hyn\Tenancy\Tests; +use Hyn\Tenancy\Environment; use Hyn\Tenancy\Providers\TenancyProvider; use Hyn\Tenancy\Providers\WebserverProvider; use Hyn\Tenancy\Tests\Traits\InteractsWithBuilds; @@ -94,6 +95,14 @@ protected function setUp() : void parent::setUp(); $this->migrateSystem(); + + // The application boots before this harness creates the schema, which + // no real one does: the environment decided tenancy was not installed. + // Building it again here, rather than leaving it to whoever asks + // first, keeps the request itself looking like a real one. + $this->app->forgetInstance(Environment::class); + $this->app->make(Environment::class); + $this->duringSetUp($this->app); }