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

Decorator Bundle Laravel Package

yceruto/decorator-bundle

A Symfony bundle for applying the decorator pattern to services. Wrap existing implementations with extra behavior, keep original classes untouched, and compose features cleanly for more modular, maintainable applications.

View on GitHub
Deep Wiki
Context7

Getting Started

First, orient yourself: this is a Symfony bundle, not a Laravel package. There is no service provider, no config/decorator.php, and no Artisan command. If you are evaluating it for a Laravel codebase, treat it as a reference implementation of attribute-driven service decoration, or as a dependency you'd only touch inside a Symfony service (e.g. a shared library, a Symfony-based admin app, or a package you're porting).

Minimal steps in a Symfony host:

composer require yceruto/decorator-bundle
  • Register DecoratorBundle in config/bundles.php — the Laravel equivalent (bootstrap/providers.php) does not exist here.
  • Ensure the services you want decorated are autoconfigured/autowired so the bundle's compiler pass can see the attributes.
  • Clear the container cache after any attribute change (bin/console cache:clear); decoration is resolved at compile time, not runtime.

Where to look first: the bundle's Attribute/ directory (the #[Decorate]-style attributes and, as of v1.2.3, the Compound decorator attribute), then the DependencyInjection/CompilerPass that consumes them. The README examples are the fastest path to a working setup.

First use case: wrap an existing service with cross-cutting behaviour — logging, caching, metrics, feature-flag gating — without editing the original class or hand-writing a service definition. In Laravel you'd reach for $this->app->extend(), a bound interface, or a middleware/pipeline; here you drop an attribute on the decorator class and let the container rewrite the wiring.

Implementation Patterns

Attribute-on-decorator (the primary pattern). Put the decoration attribute on your decorator class, implement the same interface as the decorated service, and inject the inner service via the constructor. The compiler pass rewires the original service id to your decorator and moves the original to a renamed/inner id. This is the pattern to copy if you're building something similar in Laravel with Container::extend().

Compound / stacked decoration. When a service needs several decorators (logging and caching and validation), the compound decorator attribute lets you declare the stack in one place with an explicit order rather than relying on tag priorities scattered across files. Order matters: first in the stack is outermost. This is the piece touched by v1.2.3.

Explicit priority. Where multiple independent decorators target the same service, use priority to make the nesting deterministic. Never rely on discovery order — it's filesystem-dependent and will bite you in CI vs. local.

Laravel-side equivalents. When you carry these ideas back to Laravel:

// Single decorator
$this->app->extend(Cache::class, fn ($inner, $app) => new LoggingCache($inner));

// Interface-bound decorator
$this->app->bind(Notifier::class, fn ($app) => new SlackNotifier(
    $app->make(WebhookNotifier::class)
));

For multi-decorator stacks, a small Pipeline over a list of decorator classes gets you the "compound" behaviour without a compiler pass — resolve the innermost concrete, then fold the decorators over it in a config-driven order.

Integration tip: the decorator classes themselves are plain PHP and framework-agnostic. If you like the ergonomics, define the decorators once and wire them by attribute in Symfony and by hand in Laravel; only the wiring is framework-specific.

Gotchas and Tips

v1.2.3 is a namespace fix — audit your imports. The release updates the Compound decorator attribute's namespace. Patch-level, so no behavioural breaking change, but if you referenced the old fully-qualified attribute class name directly — in your own attributes, a custom compiler pass, a use statement, an IDE inspection config, or a PHPStan baseline — update those references. Attribute discovery at runtime will simply not match a stale FQCN, and the failure mode is silent: the decorator is never applied and you get the undecorated service with no error. If you want to detect this, assert on the resolved class of the service in a smoke test.

Compiled container is the #1 debugging trap. Attributes are read once at compile time. Edits to attributes (namespace, priority, target service) require a cache clear/container rebuild. A "my decorator isn't applied" bug is almost always a stale container.

Verify with the container debugger. bin/console debug:container Your\Service\Id shows the class the id actually resolves to — if it isn't your decorator, the attribute wasn't picked up (wrong namespace, service not autoconfigured, or excluded from discovery).

Autoconfiguration prerequisite. The pass only sees services registered with autoconfigure: true (or explicitly tagged). Manually defined services in YAML/XML that aren't tagged will be invisible. There is no Laravel-style "it just works" here.

Ambiguous stacks fail quietly. Without priorities, two decorators of the same service produce non-deterministic nesting. Pin them explicitly.

Extension points: the compiler pass and the service tags it reads. If you need conditional decoration (e.g. only in dev), do it via container parameters/environment rather than logic inside the decorator — keeping the decorator single-purpose makes it portable to Laravel later.

Don't look for Artisan/queue/HTTP integration. No commands, no config publishing, no facades. Scope your expectations accordingly.

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.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log