Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Sf Container Injector Laravel Package

rollerworks/sf-container-injector

A Symfony component that injects services from the container into objects and controllers, enabling lazy setter-based dependency injection without constructor wiring. Useful for legacy code and optional dependencies.

View on GitHub
Deep Wiki
Context7

Getting Started

Read this first: the package is archived (last release 2014-03-12, zero dependents). The "getting started" advice for rollerworks/sf-container-injector is therefore conditional: use it only to understand or maintain an existing Symfony 2.x-era application that already depends on it. Do not add it to a new project — Symfony's native container features have fully superseded it for a decade.

What it does, in one sentence: it gives you a small helper that pushes the Symfony service container into arbitrary objects at runtime, so legacy classes that aren't services (entities, value objects, form types, controllers, factories) can pull dependencies out of the container lazily instead of having them constructor-injected.

Minimal steps if you must install it:

composer require rollerworks/sf-container-injector

Check composer.json first — it targets PHP 5.3+ and Symfony 2.x (symfony/dependency-injection ~2.3/2.4). On PHP 7.2+ or Symfony 3+, expect to pin, patch, or fork.

Where to look, in order:

  1. README.md — usually the only usage documentation that exists.
  2. src/ — the entire public surface is small: an injector class (something like ContainerInjector) plus a marker/aware interface that your class implements to opt in.
  3. Tests/ — the test suite is the most reliable spec for the injection semantics (what happens on a missing service, whether injection is lazy, whether it recurses).
  4. The service definition XML/YAML shipped in the package — you need to know the service ID to wire it up.

First use case: a legacy class that needs one or two services but is instantiated by hand (not by the container):

use Rollerworks\Component\ContainerInjector\ContainerAwareInterface;

class LegacyReportBuilder implements ContainerAwareInterface
{
    use ContainerAwareTrait; // or implement setContainer() manually

    public function build()
    {
        $mailer = $this->container->get('mailer');
        // ...
    }
}

Then, wherever you construct it:

$builder = new LegacyReportBuilder();
$injector->inject($builder); // the package's whole reason to exist

Implementation Patterns

1. Register the injector once, treat it as infrastructure. Wire the package's service in your bundle's services.yml/services.xml and inject the injector, not the container, into the few places allowed to create legacy objects (usually a factory or a controller base class). Centralising it makes the eventual migration grep-able — one service, one call site.

2. Setter injection at construction boundaries. The standard pattern is: create object → inject → use. Do it in the factory that owns the object's lifecycle, immediately after new, so no code path can observe a half-initialised object.

public function createBuilder(): LegacyReportBuilder
{
    $builder = new LegacyReportBuilder();
    $this->containerInjector->inject($builder);

    return $builder;
}

3. Lazy resolution for optional/expensive services. The main historical justification for this pattern: a class needs a service only on a rarely-hit branch (e.g., a PDF renderer inside an exporter). Constructor injection would force the dependency everywhere. Resolving inside the method defers it:

public function export(Report $report)
{
    if ($report->isPdf()) {
        return $this->container->get('app.pdf_renderer')->render($report);
    }

    return $report->toArray();
}

Use this deliberately and sparsely. It is a service locator, and the usual service-locator trade-offs apply.

4. Prefer constructor injection wherever the object is a service. The injector is for objects the container cannot own. If the class is registered in services.yml, just autowire it. Mixing both in one class creates two resolution paths and confuses debugging.

5. Test doubling. Because the injector takes the container as a collaborator, unit tests can bypass it entirely — construct the object and call setContainer() with a ContainerBuilder/mock containing only the services under test:

$container = new ContainerBuilder();
$container->set('mailer', $mailerMock);

$builder = new LegacyReportBuilder();
$builder->setContainer($container);

6. Migration bridge. If you're modernising, the highest-value pattern is: add the aware interface to the class, inject via the package today, and mark the class with a TODO to become a real service. Do not expand the injector's reach — every new inject() call is future debt.

7. Modern replacement mapping. When you migrate, these are the drop-in equivalents:

Old pattern Native Symfony replacement
Container injected into a service Constructor autowiring (2.8+/3.0+)
Container injected into a lazy branch of a service ServiceSubscriberInterface (3.3+) with a ServiceLocator
Setter injection of a specific dependency @required setter / #[Required]
Objects created outside the container A factory service, or ServiceLocator passed explicitly
Container in a controller AbstractController + getParameter()/typed constructor args

Gotchas and Tips

  • It is a service locator, and it will be abused. The single biggest failure mode is that inject() calls spread from one legacy class to twenty, and the container becomes an untraceable global. If you inherit this, treat every ContainerAwareInterface implementation as a migration TODO and cap the count.
  • Private services will break it on Symfony 3.4+. Symfony deprecated and then removed public-by-default container access (4.0). Any $this->container->get('service') on a non-public service throws. This alone usually forces the migration before anything else breaks.
  • ContainerAwareInterface/ContainerAwareTrait were deprecated in Symfony 4.4 and removed in 5.0. If you upgrade Symfony, this package's interface and Symfony's diverge and you'll get confusing "class exists twice" or "method not found" errors. Fork the interface into your own namespace as the first step of a port.
  • PHP compatibility is the hard blocker. A 2014 package will hit removed functions and syntax. Expect to pin composer.json to an old PHP, or vendor/fork the ~2–5 files and fix them. Given the size, forking is usually cheaper than fighting the constraint resolver.
  • No security support, no maintainer, no releases since 2014. Any CVE in the dependency tree is yours. Do not run it in a codebase with an active security SLA without at least vendoring the code into your repo so you can audit it.
  • Check the ordering semantics in the tests. Whether inject() is recursive, whether it throws or no-ops on a class that doesn't implement the marker interface, and whether it overwrites an already-set container are all behaviours worth confirming rather than assuming — the 2014 docs won't tell you.
  • Debugging is opaque. Stack traces lose the real dependency graph, and debug:container won't show which classes received the container. Add a temporary log line in your factory when chasing a "service not found" that only appears in one code path.
  • Do not use it for entities or domain objects. Injecting infrastructure into your model layer is how this pattern becomes unfixable. If an entity needs a service, the service should accept the entity as an argument instead.
  • Extension point is effectively none. There's no compiler pass, no tagging, no configurability worth relying on. If you need different behaviour, replace the package rather than extend it — the codebase is small enough that a hand-rolled injector plus ServiceSubscriberInterface will be both shorter and supported.
  • Scoring context: opportunity 12.89, stars 0, dependents 0. The number is arguably too high for a dead 2014 library — treat the score as "small but coherent code someone could read in an hour," not as a recommendation to adopt.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core