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

Aslan Solid Package Laravel Package

aslan-asilon31/aslan-solid-package

Laravel package showcasing SOLID principles with a clean, modular structure. Provides example abstractions and patterns to organize services, keep dependencies decoupled, and improve maintainability in real-world apps.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require aslan-asilon31/aslan-solid-package
    

    Add the service provider to config/app.php under providers:

    Aslan\SolidPackage\SolidServiceProvider::class,
    
  2. First Use Case: Dependency Inversion Use the built-in Contract and Implementation classes to enforce SOLID principles. Example:

    use Aslan\SolidPackage\Contracts\LoggerContract;
    use Aslan\SolidPackage\Implementations\FileLogger;
    
    // Define a contract
    class LoggerContract extends \Aslan\SolidPackage\Contracts\BaseContract {
        public function log(string $message);
    }
    
    // Bind the contract to an implementation
    app()->bind(LoggerContract::class, function ($app) {
        return new FileLogger($app->make('path.log'));
    });
    
    // Usage
    $logger = app()->make(LoggerContract::class);
    $logger->log("Test message");
    
  3. Where to Look First

    • Contracts: vendor/aslan-asilon31/aslan-solid-package/src/Contracts/
    • Implementations: vendor/aslan-asilon31/aslan-solid-package/src/Implementations/
    • Documentation: Check the README.md for basic examples and usage.

Implementation Patterns

Dependency Inversion Principle (DIP)

  • Pattern: Use contracts to define interfaces and bind them to implementations in the service container.

    // Define a contract
    class PaymentProcessorContract extends \Aslan\SolidPackage\Contracts\BaseContract {
        public function processPayment(float $amount);
    }
    
    // Bind to a specific implementation
    app()->bind(PaymentProcessorContract::class, StripePaymentProcessor::class);
    
  • Workflow:

    1. Define contracts for all external dependencies.
    2. Bind contracts to implementations in AppServiceProvider or a dedicated config file.
    3. Inject contracts into classes rather than concrete implementations.

Single Responsibility Principle (SRP)

  • Pattern: Use the package’s Service and Repository classes to encapsulate logic.

    use Aslan\SolidPackage\Services\BaseService;
    
    class UserService extends BaseService {
        public function registerUser(array $data) {
            // Only handle user registration logic
            $this->repository->create($data);
        }
    }
    
  • Integration Tips:

    • Keep services thin and focused on a single responsibility.
    • Use repositories for data access logic.

Open/Closed Principle (OCP)

  • Pattern: Extend existing contracts or implementations without modifying them.

    // Extend a base implementation
    class CustomLogger extends \Aslan\SolidPackage\Implementations\BaseLogger {
        public function log(string $message) {
            // Custom logic
            parent::log($message);
        }
    }
    
  • Tip: Use traits or inheritance to add functionality while keeping the base class closed.

Liskov Substitution Principle (LSP)

  • Pattern: Ensure implementations adhere to contract signatures.

    class InvalidLogger implements LoggerContract {
        public function log(string $message) {
            // This violates LSP if the contract expects a return value
        }
    }
    
  • Tip: Use PHPStan or Psalm to enforce type safety and contract compliance.

Interface Segregation Principle (ISP)

  • Pattern: Split large contracts into smaller, focused ones.
    // Instead of one monolithic contract
    class MonolithicContract extends \Aslan\SolidPackage\Contracts\BaseContract {
        public function log(string $message);
        public function sendEmail(string $to);
    }
    
    // Split into smaller contracts
    class LoggerContract extends \Aslan\SolidPackage\Contracts\BaseContract {
        public function log(string $message);
    }
    
    class EmailSenderContract extends \Aslan\SolidPackage\Contracts\BaseContract {
        public function sendEmail(string $to);
    }
    

Gotchas and Tips

Pitfalls

  1. Over-Engineering Contracts

    • Avoid creating contracts for trivial or one-off use cases. Stick to high-level abstractions.
    • Fix: Use contracts only for dependencies that will change or have multiple implementations.
  2. Tight Coupling in Bindings

    • Binding contracts to implementations too early can lead to inflexibility.
    • Fix: Use environment-based bindings or config files for dynamic switching.
  3. Ignoring the Service Container

    • Manually instantiating implementations instead of using the container defeats the purpose of DIP.
    • Fix: Always resolve dependencies via app()->make() or constructor injection.
  4. Missing Abstract Classes

    • The package may lack abstract base classes for common use cases (e.g., repositories, services).
    • Fix: Extend Aslan\SolidPackage\BaseService or Aslan\SolidPackage\BaseRepository for consistency.

Debugging

  • Contract Not Found Errors

    • Ensure contracts are properly namespaced and extend BaseContract.
    • Debug: Run php artisan container:list to verify bindings.
  • Implementation Not Resolvable

    • Check if the implementation class exists and is autoloaded.
    • Debug: Use app()->has(Implementation::class) to test resolution.

Config Quirks

  • No Built-in Config File
    • The package doesn’t include a config file by default. Bindings must be manually set in AppServiceProvider.
    • Tip: Create a solid.php config file for centralized bindings:
      return [
          'bindings' => [
              LoggerContract::class => FileLogger::class,
              // Add more bindings here
          ],
      ];
      
      Then load it in AppServiceProvider:
      $this->app->bind(config('solid.bindings')[LoggerContract::class] ?? null);
      

Extension Points

  1. Custom Contracts

    • Extend Aslan\SolidPackage\Contracts\BaseContract to create domain-specific contracts.
    • Example:
      namespace App\Contracts;
      
      use Aslan\SolidPackage\Contracts\BaseContract;
      
      class CacheContract extends BaseContract {
          public function get(string $key);
          public function set(string $key, $value);
      }
      
  2. Middleware for Contracts

    • Use Laravel middleware to validate contract implementations before resolution.
    • Example:
      $kernel->pushMiddleware(function ($request, $next) {
          if ($request->wantsJson() && app()->bound(LoggerContract::class)) {
              $logger = app()->make(LoggerContract::class);
              if (!$logger instanceof \Aslan\SolidPackage\Implementations\BaseLogger) {
                  abort(500, "Invalid logger implementation");
              }
          }
          return $next($request);
      });
      
  3. Testing Contracts

    • Mock contracts in tests to isolate dependencies.
    • Example:
      $this->mock(LoggerContract::class)->shouldReceive('log')->once();
      
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle