Weave Code
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

Prototype Laravel Package

spiral/prototype

Prototype generation tools for Spiral Framework to speed up application scaffolding. Provides helpers to define models, repositories, and services with less boilerplate, keeping code consistent while accelerating development and iteration.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add via Composer:

    composer require spiral/prototype
    

    Require the package in bootstrap/app.php (Laravel 8+):

    $app->register(\Spiral\Prototype\PrototypeServiceProvider::class);
    
  2. First Use Case: Auto-Wiring a Class Define a class with type-hinted dependencies (no manual binding needed):

    class UserService {
        public function __construct(private UserRepository $repository) {}
    }
    

    Laravel’s container will now auto-resolve UserRepository via spiral/prototype.

  3. Where to Look First

    • PrototypeServiceProvider: Registers the AST-based dependency resolver.
    • config/prototype.php: Default settings (e.g., ignored namespaces, custom resolvers).
    • app/Providers/AppServiceProvider.php: Override default behavior via Prototype::extend().

Implementation Patterns

Core Workflows

  1. Auto-Wiring Without Bindings Replace manual bind() calls with type-hinted constructors:

    // Before
    $app->bind(UserService::class, function ($app) {
        return new UserService($app->make(UserRepository::class));
    });
    
    // After (spiral/prototype handles it)
    
  2. Custom Resolvers Extend for non-standard dependencies (e.g., closures, dynamic classes):

    Prototype::extend(function ($container, $abstract, $parameters) {
        if ($abstract === Closure::class) {
            return fn() => new DynamicClass(...$parameters);
        }
    });
    
  3. Ignoring Namespaces Exclude specific namespaces from auto-wiring in config/prototype.php:

    'ignored_namespaces' => [
        'App\IgnoredNamespace\\',
    ],
    
  4. Integration with Laravel’s Container Use alongside Laravel’s built-in DI:

    // Works seamlessly with Laravel’s make()/singleton()
    $service = app()->make(UserService::class);
    

Advanced Patterns

  • Dynamic Class Resolution Resolve classes defined at runtime (e.g., via config):

    Prototype::extend(function ($container, $abstract) {
        if (is_string($abstract) && class_exists($abstract)) {
            return $container->make($abstract);
        }
    });
    
  • Parameter Overrides Pass constructor arguments dynamically:

    $service = app()->makeWith(UserService::class, ['repository' => $customRepo]);
    

Gotchas and Tips

Common Pitfalls

  1. AST Limitations

    • Issue: Nested closures or dynamic new calls may not resolve. Fix: Use explicit bindings or custom resolvers.
    • Debugging: Enable prototype.debug in config to log unresolved classes.
  2. Circular Dependencies

    • Issue: spiral/prototype may not handle circular references like Laravel’s container. Fix: Refactor to use interfaces or inject the container itself.
  3. Namespace Conflicts

    • Issue: Classes in ignored namespaces might still resolve if referenced indirectly. Fix: Double-check ignored_namespaces and use fully qualified names.
  4. Performance Overhead

    • Issue: AST parsing adds startup time. Fix: Disable in production if unused ('enabled' => env('APP_ENV') !== 'production').

Debugging Tips

  • Log Unresolved Classes Enable debug mode in config/prototype.php:

    'debug' => true,
    

    Check Laravel logs for PrototypeResolver warnings.

  • Override Resolvers Temporarily Use Prototype::extend() in a service provider to test custom logic without modifying core files.

Extension Points

  1. Custom Resolver Priority Register resolvers in reverse order of priority (last registered wins):

    Prototype::extend($customResolver1);
    Prototype::extend($customResolver2); // Higher priority
    
  2. Post-Resolution Hooks Modify instances after resolution:

    Prototype::extend(function ($container, $abstract) {
        $instance = $container->make($abstract);
        if ($abstract === UserService::class) {
            $instance->setLogger(app()->make(Logger::class));
        }
        return $instance;
    });
    
  3. Integration with Packages

    • Issue: Some packages (e.g., laravel/tinker) may bypass the container. Fix: Patch the package’s bootstrap or use app()->bind() as a fallback.
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor