Halloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanHalloween DealsAmazon USOctober picks are moving - compare before checkoutAmazon US: current deals, useful picks and tech finds.See Picks×
FREEDOM251

Freedom251 › Blog › Dependency Injection

Tired of “new” Everywhere? Learn Factory Method with Laravel

By Freedom251 Team · · 3 min read

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If you’re tired of “new” everywhere, Laravel’s service container can help keep callers from depending directly on concrete classes. The usual starting point is constructor injection: depend on an interface, bind it to an implementation in a service provider, and let Laravel resolve it where dependency injection is supported. That reduces coupling; it does not make new inherently wrong or mean every object needs a factory.

What Factory Method means—and what it doesn’t

The classic Factory Method pattern delegates product creation to a method whose concrete product can vary, classically through creator subclasses. It addresses a creation decision by moving that decision out of the code that uses the product.

As an Amazon Associate I earn from qualifying purchases.

Laravel’s service container can address a related problem: callers need not construct a particular implementation themselves. But a container binding is framework-managed dependency resolution, not automatically a textbook Factory Method. The distinction matters because calling every object-returning mechanism a “factory” blurs how the code actually chooses an implementation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Laravel describes its container as “a powerful tool for managing class dependencies and performing dependency injection.” Laravel’s service-container documentation covers automatic resolution and interface bindings.

How to avoid scattering implementation-specific construction

Suppose several services create new SmtpNotifier() directly. If the application later needs a different notifier, every caller that knows about that concrete class may need to change. Introduce an interface when there is a genuine implementation choice or a useful substitution seam, bind it once, and have consumers request the interface.

1. Define the contract and implementation

<?php

namespace AppContracts;

interface Notifier
{
    public function send(string $message): void;
}
<?php

namespace AppServices;

use AppContractsNotifier;

class SmtpNotifier implements Notifier
{
    public function send(string $message): void
    {
        // Send the message through the configured mail transport.
    }
}

2. Bind the interface in a service provider

Register the mapping in a provider’s register method. Laravel’s provider documentation identifies this method as the place to register container bindings. Use the provider appropriate to your application and Laravel version.

<?php

namespace AppProviders;

use AppContractsNotifier;
use AppServicesSmtpNotifier;
use IlluminateSupportServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->bind(Notifier::class, SmtpNotifier::class);
    }
}

Here, bind tells the container which implementation to resolve for the interface. It is not a rule that every dependency must be registered: Laravel can automatically resolve many concrete classes when their dependencies are resolvable.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

3. Type-hint the contract in a framework-resolved consumer

<?php

namespace AppServices;

use AppContractsNotifier;

class WelcomeMessage
{
    public function __construct(private Notifier $notifier)
    {
    }

    public function send(string $name): void
    {
        $this->notifier->send("Welcome, {$name}!");
    }
}

When Laravel constructs WelcomeMessage through a framework-supported injection point, it can resolve the type-hinted interface using the registered binding. The consumer knows the contract, not the specific notifier class. Laravel documents automatic resolution for many framework-managed classes; this does not mean arbitrary code can rely on injection without being constructed or invoked through the framework.

For the full mechanics and current-version details, see Laravel’s service-container documentation and its service-provider documentation.

Choose the simplest creation mechanism that fits

There is no need to replace every new with a factory. The useful question is whether the construction choice varies and who should own that choice. These are practical decision aids, not Laravel-mandated rules.

Approach Who chooses the implementation? Best fit Trade-off
Direct construction The caller names the concrete class. A simple object with fixed, straightforward construction and no meaningful substitution need. Callers depend on the concrete class and may need edits if that choice changes.
Constructor injection of a concrete class The dependency is explicit in the constructor; Laravel can resolve many concrete classes automatically at framework injection points. A fixed dependency whose construction is manageable and whose abstraction would not add value. The consumer still depends on that concrete type.
Interface binding with constructor injection The container uses the registered binding. A stable contract with an implementation chosen by application configuration or a need to substitute the dependency in tests. Adds an interface and binding to maintain; useful only when that seam earns its complexity.
Explicit factory The factory method or object makes the choice. Creation rules vary at runtime or involve enough logic that a distinct creation component makes them clearer. Adds indirection; unnecessary when it merely repeats a fixed container binding.

Constructor injection also makes dependencies visible and lets tests provide an alternate implementation through the contract. Resolving dynamically from the container inside application code can hide dependencies from the constructor; reserve that style for cases where dynamic resolution is actually needed.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Don’t confuse service resolution with Eloquent model factories

Laravel Eloquent factories solve a different problem: they define model attributes for database seeding and tests. Laravel documents generating one with php artisan make:factory and accessing model factories through the HasFactory trait. They are not the mechanism for selecting a runtime service implementation. See Laravel’s Eloquent factory documentation.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Dependency InjectionFactory MethodLaravelPHPService Container

Leave a Reply

Your email address will not be published. Required fields are marked *

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.