Great question! The best practice in Laravel for using services inside controllers is dependency injection. This allows Laravel’s service container to handle the resolution of dependencies, and you get the benefits of loose coupling, easier testing, and improved code clarity.
1. Constructor Injection (Recommended)
Pros:
- Services are automatically resolved by the container.
- Easy to mock for unit testing.
- Clear code structure.
You can type-hint your services in the controller's constructor:
use App\Services\EventService;
use App\Services\LocationService;
use App\Services\TypeService;
class MyController extends Controller
{
protected $eventService;
protected $locationService;
protected $typeService;
public function __construct(
EventService $eventService,
LocationService $locationService,
TypeService $typeService
) {
$this->eventService = $eventService;
$this->locationService = $locationService;
$this->typeService = $typeService;
}
public function someMethod()
{
// Use $this->eventService as needed
}
}
If you don't need all services for all actions, consider method injection instead:
2. Method Injection
Inject only the services you need into individual controller methods:
use App\Services\EventService;
public function store(Request $request, EventService $eventService)
{
$eventService->someMethod();
}
This way, services are only resolved if/when that method is called.
3. Using app()->make(...)
app()->make(EventService::class)->someMethod();
This does work, but it's less clean, harder to test, and violates the principle of relying on abstractions instead of concrete classes. Avoid this for regular usage except in rare dynamic cases.
4. Instantiating services manually (new EventService)
Avoid this, as it binds you to the concrete class, and you lose out on the ability to inject dependencies into those services (e.g., services that need a repository, etc).
Summary:
- Use constructor injection if you always need the services.
- Use method injection if you only need them for some methods.
- Prefer dependency injection over manually creating instances or using the service container for regular controller actions.
Let me know if you have more specific use-cases in mind!