prolix/di-extra-bundle
Prolix DI Extra Bundle adds convenient dependency-injection helpers to Symfony applications, extending the standard container with extra configuration options, service decoration shortcuts, and autowiring conveniences so you can wire services with less boilerplate.
This is a patch release (2.0.1) that adds Symfony 4 support to the 2.0 line. There are no recorded breaking changes, so if you are already on 2.0.0 the upgrade path is a plain composer update. Start by confirming what your lockfile actually resolves to before assuming anything changed in your app:
composer require vendor/package:^2.0.1
composer show vendor/package # confirm 2.0.1 is installed
composer why-not vendor/package 2.0.1 # surfaces any blocking constraint
First things to inspect, in order:
composer.json of the package — check the require block for symfony/* constraints. Symfony 4 support usually means the constraint was widened to ^3.4|^4.0, which can quietly bump your minimum PHP (Symfony 4 requires PHP 7.1+).extra.laravel.providers). If it is, do not add it to config/app.php; double registration causes duplicate bindings and duplicated config merges.config/ in the package — run php artisan vendor:publish --provider="Vendor\Package\PackageServiceProvider" (or --tag=package-config) and read the published file top to bottom before touching anything. Most "it doesn't work" reports trace back to a config key the developer never saw.First use case: wire up a single feature end-to-end in a scratch route or artisan command, resolve the package's main class from the container by type-hint (not app('alias')), and confirm it behaves. Once that works, move it into a service class. Resolving via the container is what proves the provider's bindings are correct — an instantiated-by-hand object will hide misconfiguration.
If you maintain a package or a shared library that consumes this one, the interesting part of 2.0.1 is not Laravel at all: it means the same code path now runs against Symfony 4's container and console. Test that path separately rather than assuming Laravel green means Symfony green.
Constructor injection over facades. Resolve the package's services through the container in constructors. Facade aliases are convenient but they hide the dependency from static analysis and make it impossible to swap in a fake without Facade::swap gymnastics in tests.
final class SyncOrders
{
public function __construct(private readonly OrderClient $client) {}
public function __invoke(Order $order): void
{
$this->client->push($order->toArray());
}
}
Bind once, in one place. If you need to vary behaviour (different credentials, different transport, a test double), bind an interface to the package's implementation in your own AppServiceProvider rather than reaching into the package's provider. This keeps upgrades cheap: package internals change, your binding line does not.
Config is the integration surface. Prefer config values over subclassing package classes. Subclassing couples you to method signatures the maintainer does not consider public API, and 2.x minor releases are free to change them.
Queue and event boundaries. Anything that touches the network belongs behind a job. Dispatch a job that resolves the client from the container; do not inject a live client into a model or a controller that also does request work. This is also the easiest way to get retries and backoff for free.
Testing pattern. Use the container to substitute:
$this->app->instance(OrderClient::class, new FakeOrderClient());
Then assert on the fake. Avoid Http::fake()-style global fakes layered on top of the package's own HTTP layer unless you know which one wins — you can end up asserting against a fake that never ran.
Version pinning across frameworks. Because 2.0.1 broadens Symfony support, you may now have one package version shared between a Laravel app and a Symfony service. Pin ^2.0.1 in both, run the test suites of both, and only then treat the shared constraint as safe. Do not let the Laravel app float on ^2.0 while the Symfony app floats independently — you will get a split resolution and a bug that reproduces in exactly one environment.
Migration shape for the 2.0 line. If you are coming from 1.x, do the framework-support upgrade as its own commit with no behaviour changes, then change behaviour in a second commit. Patch releases that widen framework constraints are exactly the kind of thing that should be isolated so a git bisect later points at one commit.
Symfony 4 dropped ContainerAware. If you extend or copy any package class that used ContainerAwareInterface/ContainerAwareTrait, that path is gone in Symfony 4. Use PSR-11 ContainerInterface injection instead. Laravel's container satisfies PSR-11, so the same code works in both — this is the main reason the Symfony 4 bump is worth taking.
PHP floor moved. Symfony 4 requires PHP 7.1. Check your CI matrix and any platform.php config in composer.json. A platform override of 7.0 will make Composer silently resolve to an older package version and you will spend an hour debugging code that "isn't there".
Auto-discovery vs manual registration. If you upgraded from a Laravel version before 5.5, or you copied an old config/app.php, you may have a manual provider entry that now duplicates the discovered one. Symptom: config merged twice, listeners fired twice, or vendor:publish showing two tags.
Config caching bites in production only. php artisan config:cache freezes config at boot. If you register a provider that reads config in register() and you change an env var, nothing happens until you re-cache. Reproduce production bugs with config:cache on locally before declaring them unreproducible.
Debugging resolution order. When a class resolves to the wrong implementation, use app()->getBindings() or a one-off dd(app()->make(SomeInterface::class)) in a route. Nine times out of ten the package's provider registered before yours and yours lost, or vice versa — ordering is decided by discovery order and your AppServiceProvider, not by wishful thinking.
Extension points that are actually stable. Config values, container bindings, published views/translations, and documented events are safe. Method overriding, protected properties, and traits are not. Before 2.x, note which of these you rely on and add a test that fails loudly if it changes.
Read the diff, not the changelog. "Symfony 4 supported" in a patch release means Composer constraints and possibly some @internal adjustments. composer diff or a glance at the tag comparison tells you in two minutes whether anything touched the Laravel code path. For a single-line changelog, that is worth doing once — it is also how you catch an accidental constraint loosening that lets an untested Symfony 5 in later.
Do not upgrade for the changelog alone. If you are Laravel-only and healthy on 2.0.0, 2.0.1 is low-value. Take it when you next touch dependencies, or immediately if you need the Symfony 4 path. Batching it with unrelated dependency updates is how an innocuous patch becomes a bisect target.
How can I help you explore Laravel packages today?