--- title: Early identification extends: _layouts.documentation section: content --- # Early identification A slight "gotcha" with using the automatic approach to transition the application's context based on a route middleware is that **route-level middleware is executed after controller constructors.** The implication of this is if you're using dependency injection to inject some services in the controller constructors, **they will read from the central context**, because route-level middleware hasn't initialized tenancy yet. There are two ways to solve it, the former of which is preferable. ## Not using constructor DI You can inject dependencies in route **actions**, meaning: If you have a route that binds a `Post` model, you can still inject dependencies like this: ```php // Note that this is sort-of pseudocode. Notice the route action DI // and just skim the rest :) Route::get('/post/{post}/edit', 'PostController@edit'); class PostController { public function edit(Request $request, Post $post, Cloudinary $cloudinary) { if ($request->has('image')) { $post->image_url = $cloudinary->store($request->file('image')); } } } ``` If you don't like that because you access some dependency from many actions, consider creating a memoized method: ```php class PostController { protected Cloudinary $cloudinary; protected cloudinary(): Cloudinary { // If you don't like the service location here, injecting Application // in the controller constructor is one thing that's 100% safe. return $this->cloudinary ??= app(Cloudinary::class); } public function edit(Request $request, Post $post) { if ($request->has('image')) { $post->image_url = $this->cloudinary()->store( $request->file('image') ); } } } ``` ## Using a more complex middleware setup > Note: There's a new MW in v3 for preventing access from central domains. v2 was doing this a bit differently. The manual for implementing this will come soon, for now you can look at how 2.x does this. In short: The `InitializeTenancy` mw is part of the global middleware stack, which doesn't have access to route information, but is executed prior to controller constructors. The `PreventAccessFromTenantDomains` mw checks that we're vising a tenant route on a tenant domain, or a central route on a central domain — and if not, it aborts the request, either by 404 or by redirecting us to a home url on the tenant domain. Here's the logic visually: ![Early identification middleware](/assets/images/stancl_tenancy_middleware.png) And here are the relevant files in 2.x codebase: - [https://github.com/stancl/tenancy/blob/2.x/src/Middleware/InitializeTenancy.php](https://github.com/stancl/tenancy/blob/2.x/src/Middleware/InitializeTenancy.php) - [https://github.com/stancl/tenancy/blob/2.x/src/Middleware/PreventAccessFromTenantDomains.php](https://github.com/stancl/tenancy/blob/2.x/src/Middleware/PreventAccessFromTenantDomains.php)