wynd/nihilus-symfony-resolver
Symfony resolver integration for Wynd Nihilus, helping wire Nihilus components into Symfony applications. It provides resolver support to simplify service discovery and dependency resolution in Symfony projects.
This is a Symfony Bundle, not a Laravel package — so the first real step is deciding whether you actually need it. The wynd/nihilus-symfony-resolver bundle wires up the Nihilus service resolver pattern (lazy service lookup by interface) into a Symfony DI container. If you are building a Laravel app, you are almost certainly better served by a small custom resolver built on Laravel's container than by installing this bundle.
If you are maintaining a Symfony component inside a Laravel codebase (or bridging a Symfony library), start here:
composer require wynd/nihilus wynd/nihilus-symfony-resolver
config/bundles.php:
return [
Wynd\Nihilus\Symfony\NihilusBundle::class => ['all' => true],
];
use Wynd\Nihilus\ResolverInterface;
final class MyService
{
public function __construct(private ResolverInterface $resolver) {}
public function handle(): void
{
$handler = $this->resolver->resolve(HandlerInterface::class);
$handler->execute();
}
}
DependencyInjection/ directory of the bundle first — there is very little code, so the extension class is where all the wiring lives.For a Laravel-only project, the "first use case" is usually a strategy/plugin resolver — resolving a concrete implementation of an interface at runtime — which Laravel's built-in tagged() binding already handles without adding this bundle.
Interface-based service lookup (the core pattern).
Nihilus flips the usual Symfony approach: instead of tagging services and injecting iterable $handlers, you inject a single resolver and resolve by contract:
$resolver->resolve(PaymentGatewayInterface::class); // one
$resolver->resolve(PaymentGatewayInterface::class, true); // all matching
This lets you add implementations without touching the consumer — a good fit for plugin-style architectures.
Wiring an implementation as a Nihilus service.
In Symfony you register services as usual (typically _instanceof or autoconfigure), and the bundle's DI extension builds the resolver/locator on top. Keep service definitions explicit (services.yaml) so autowiring picks up the interfaces you want resolved.
Laravel-port equivalence. If you want the same ergonomics in Laravel without the bundle, the pattern maps to:
// AppServiceProvider::register
$this->app->singleton(ResolverInterface::class, fn ($app) =>
new class($app) implements ResolverInterface {
public function __construct(private $app) {}
public function resolve(string $id, bool $all = false) {
$concrete = config("resolvers.$id");
return $all
? collect($this->app->tagged($id))->all()
: $this->app->make($concrete);
}
});
Then tag drivers in a service provider:
$this->app->tag([StripeGateway::class, PayPalGateway::class], PaymentGatewayInterface::class);
Integration tip: adapters over installation.
When you have a Symfony library you want to reuse in a Laravel app, wrap it in a thin adapter service provider rather than letting the bundle auto-register. Laravel's PackageManifest will not read Symfony bundle metadata, so nothing will happen on install — which is both a footgun and a convenience (you can safely composer require it without side effects).
Where Nihilus pays off.
It will not auto-discover in Laravel. The bundle registers through NihilusBundle::class in config/bundles.php. In Laravel, vendor/wynd/nihilus-symfony-resolver will be installed but inert. You must either run it inside a Symfony kernel or reimplement the wiring.
Zero stars, single maintainer, low signal. The opportunity score is 34.39 and there are zero dependents. Treat it as a pattern reference, not a dependency. Vendor the ~50 lines of resolver logic if you like the API, and skip the bundle.
Resolver ambiguity. With multiple implementations of an interface, resolve() will either throw or return an arbitrary one depending on the underlying locator behavior. Always call the "all" variant (resolve($id, true)) when you expect plugin sets, and validate count in your consumer.
Caching gotcha. Symfony caches the compiled container. If you add a new implementation, run cache:clear (or bin/console cache:pool:clear) — the resolver will not see it otherwise. In Laravel, php artisan optimize:clear.
Debugging the resolver.
In Symfony: bin/console debug:container --show-private and look for the Nihilus resolver service; check _instanceof rules in services.yaml.
In Laravel after porting: app()->tagged(YourInterface::class) in php artisan tinker to confirm the tag has entries.
Extension points worth knowing. The bundle's extension class is the right place to (a) alias interfaces to concrete services, (b) mark services as public if you need direct container access during debugging, and (c) conditionally register implementations based on config.
Version pinning. Last release 2024-02-15 and a 0.x-style API surface; pin an exact version in composer.json if you do use it, and add a test that instantiates the resolver so an upstream change breaks CI rather than production.
Do not expect PSR-4 class names to stay. wynd/nihilus and wynd/nihilus-symfony-resolver are split packages; a minor bump on one can break the other. Constrain both together.
How can I help you explore Laravel packages today?