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

Dice Laravel Package

level-2/dice

Dice is a lightweight, dependency-free dependency injection container for PHP. It provides automatic constructor and setter injection, factory callbacks, shared instances, and simple configuration for decoupled, testable applications.

Deep Wiki
Context7

Technical Evaluation

Architecture fit Dice is a standalone, framework-agnostic DI container built around reflection-based autowiring, construction rules, shared instances, and callbacks. That design is a poor fit for application-level use inside Laravel, because Illuminate\Container already provides constructor autowiring, singleton/scoped bindings, contextual binding, tagged bindings, and deep integration with the framework's resolution pipeline (controllers, jobs, listeners, middleware, console commands). Adopting Dice app-side creates two parallel composition roots with overlapping semantics and no shared lifecycle. The credible fit is narrower: as the internal container for a framework-agnostic domain or extraction candidate (a package we want to run outside Laravel), or as a stopgap in a legacy PHP codebase being migrated toward Laravel. In those contexts Dice's small API surface and zero-config autowiring are genuinely useful.

Integration feasibility Feasible but only as an opt-in, bounded integration. The realistic pattern is to register a configured Dice instance as a Laravel singleton and use it exclusively inside a designated module boundary, with a rule or callback that delegates unresolvable dependencies back to the Laravel container (app()), so Laravel-managed services (config, loggers, HTTP clients) remain the single source of truth. A spike to validate this bridge, PSR-11 conformance (verify — Dice's primary API is create(), and PSR-11/get() support must be confirmed rather than assumed), and PHP/Laravel version constraints against the 2023-01-17 release is roughly 2–3 engineer-days.

Technical risk

  • Dual-container ambiguity (high): engineers will not reliably know which container owns a given class; divergent singleton scopes produce subtle state bugs.
  • No compiled/cached container (medium): resolution is reflection-per-call with no build step, so per-request cost is higher than Laravel's cached bindings or Symfony's compiled container. Mitigable via shared instances and rule caching, but it is an architectural gap, not a config flag.
  • Long-lived workers / Octane (medium-high): shared instances persist for the process lifetime, which is exactly the request-state bleed failure mode Octane users are warned about; requires explicit reset hooks.
  • Maintainer concentration (medium): ~435 stars and a single-maintainer project with a low release cadence; the codebase is small and low-churn, but there is no LTS, security policy, or commercial backstop.
  • Ecosystem mismatch (medium): Laravel-specific resolution features (contextual bindings, #[Inject]-style attributes, facades, app() helpers) do not translate; interfaces without explicit rules fail at runtime, not at boot.

Key questions

  1. What concrete problem does Dice solve that Illuminate\Container cannot — is this a genuine extraction/portability requirement or incidental complexity?
  2. Does the target release satisfy our PHP and Laravel version support matrix, and does it pass a PSR-11 conformance check if we need that interop?
  3. Which classes would Dice own, and how do we enforce that boundary in CI (architecture tests) rather than by convention?
  4. What is the reset/teardown contract under Octane, queue workers, and php artisan serve?
  5. What is the exit cost if the maintainer disappears — is the surface small enough to vendor or replace with PHP-DI/Symfony DI?

Integration Approach

Stack fit Composer-installable, no extensions, no framework coupling — it will install cleanly. The misfit is conceptual, not mechanical: Laravel expects to be the composition root. Treat Dice as a module-scoped container behind an interface, never as a replacement for Illuminate\Container and never as the resolver for framework-managed entry points.

Migration path Boundary-first and incremental. Do not attempt a container swap. Identify one module with a clean public API (domain services, an extracted package, a bounded-context library). Stand up Dice inside it, expose the module to Laravel through a single service provider that binds the module's entry points into the Laravel container, and route Dice's unresolved dependencies back to Laravel via a delegate rule. If the driver is legacy modernization, invert the flow: use Dice in the legacy layer first, then progressively repoint bindings at Laravel as classes migrate — Dice becomes scaffolding that is deleted at the end, not a permanent layer.

Compatibility Validate three things before committing: the composer constraints of the 2023-01-17 release against our PHP runtime, PSR-11 conformance (or a thin adapter if we standardize on that interface), and behavior under the framework's scoped/long-lived lifecycle. Laravel's contextual bindings and attribute-based injection have no Dice equivalent, so any class relying on them must stay in the Laravel container or be refactored to explicit rules.

Sequencing

  1. Spike (2–3 days): bridge Dice to Laravel, prove autowiring + delegate resolution + reset semantics on one module.
  2. Decision gate: confirm a problem statement that the native container cannot satisfy; otherwise stop here.
  3. Pilot one low-blast-radius module in production behind a feature-flagged provider.
  4. Add architecture tests (e.g., a rule that only the module's provider may reference Dice\Dice) to prevent drift.
  5. Only then widen scope, with the Octane/worker reset contract implemented before the second module lands.

Operational Impact

Maintenance The codebase is small and stable, and the low release cadence is as much a signal of maturity as of neglect — but we inherit maintenance risk by default. Budget ownership: assign an internal owner for the dependency, pin the version, and treat any upstream abandonment as a planned vendor-and-patch rather than an incident.

Support Community-only (GitHub issues); no commercial support or security advisory process. Our team must be able to debug reflection-based resolution failures without upstream help. Because it is a contained component, the blast radius of a bug is one module rather than the whole application — provided the boundary is enforced.

Scaling Reflection-based resolution is per-call, so the cost scales with resolution frequency, not request count. Push all hot-path services to shared instances, resolve once at boot where possible, and benchmark the pilot module's p95 before widening. Under Octane or long-running workers, explicitly reset shared state on request boundaries and watch for monotonic memory growth from retained instance graphs.

Failure modes

  • Interface or scalar parameter with no rule → runtime exception at first resolution, potentially only on an unexercised code path.
  • Autowiring silently selecting a concrete class where a specific implementation was intended → wrong behavior with no error.
  • Duplicate singletons across the two containers → stale config, split caches, mock-injection failures in tests.
  • Shared instances surviving into subsequent requests under Octane → cross-request data leakage.
  • Circular dependency graphs surfacing only under production traffic.
  • Resolution divergence between test bootstrap and production bootstrap → green tests, broken deploy.

Ramp-up The API is small enough to learn in under a day, so the cost is not Dice itself — it is the second mental model. Engineers must learn when to use each container and how the bridge behaves, and onboarding docs must state the boundary rule explicitly. Expect the real ramp-up cost to land on reviewers and on whoever owns the test harness, where dual-container mocking is the most common source of friction.

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.
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
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels