title: Is it bad practice to inject several arguments to the constructor?
body: <p>I'm developing a quite complex logistics management system which will keep growing into several other ERP related modules. Therefore, I am trying to have as much of the SRP and Open/Close Principles in place for ease of extension and domain based management.</p>
  
  <p>Therefore, I decided to use Laravel and the following pattern (not sure if this has a name or not):</p>
  
  <p>I will use the PRODUCT object for my example.
  An object/entity/domain has a Class 
  <code>class ProductService {}</code></p>
  
  <p>This class has a Service Provider which is included in the providers array and is also autoloaded:
  <code>ProductServiceServiceProvider</code></p>
  
  <p>The service provider instantiate (makes) the <code>ProductRepository</code> which is an interface.
  The interface currently has a MySQL (and some Eloquent) called <code>EloquentProductRepository</code> implementation(s) and a <code>ProductRepositoryServiceProvider</code> binds the implementation which is also loaded and in the providers array.</p>
  
  <p>Now a product has many different attributes and relationships with other domains and because the other domains (or entities) need to be fully detached and again abiding with the above principle (SRP etc..) I decided to also have the same structure for them as i do for the product...I know some might think that this is too much but we need to have the system very extendable and to be honest I like to be organised and have a uniform pattern (it doesn't take that much more time and saves me a lot later).</p>
  
  <p>My question is this. The ProductService which handles all the business logic of the Product and makes the "Product" what it is will have several dependencies injected on creation of it's instance through the constructor.</p>
  
  <p>This is what it has at the moment:</p>
  
  <pre><code>namespace Ecommerce\Services\Product;
  
  use Ecommerce\Repositories\Product\ProductRepository;
  use Ecommerce\Services\ShopEntity\ShopEntityDescriptionService;
  use Content\Services\Entity\EntitySeoService;
  use Content\Services\Entity\EntitySlugService;
  use Ecommerce\Services\Tax\TaxService;
  use Ecommerce\Services\Product\ProductAttributeService;
  use Ecommerce\Services\Product\ProductCustomAttributeService;
  use Ecommerce\Services\Product\ProductVolumeDiscountService;
  use Ecommerce\Services\Product\ProductWeightAttributeService;
  use Ecommerce\Services\Product\ProductDimensionAttributeService;
  
  /**
   * Class ProductService
   * @package Ecommerce\Services\Product
   */
  class ProductService {
  
      /**
       * @var ProductRepository
       */
      protected $productRepo;
  
      /**
       * @var ShopEntityDescriptionService
       */
      protected $entityDescription;
  
      /**
       * @var EntitySeoService
       */
      protected $entitySeo;
  
      /**
       * @var EntitySlugService
       */
      protected $entitySlug;
  
      /**
       * @var TaxService
       */
      protected $tax;
  
      /**
       * @var ProductAttributeService
       */
      protected $attribute;
  
      /**
       * @var ProductCustomAttributeService
       */
      protected $customAttribute;
  
      /**
       * @var ProductVolumeDiscountService
       */
      protected $volumeDiscount;
  
      /**
       * @var ProductDimensionAttributeService
       */
      protected $dimension;
  
      /**
       * @var ProductWeightAttributeService
       */
      protected $weight;
  
      /**
       * @var int
       */
      protected $entityType = 3;
  
  
      public function __construct(ProductRepository $productRepo, ShopEntityDescriptionService $entityDescription, EntitySeoService $entitySeo, EntitySlugService $entitySlug, TaxService $tax, ProductAttributeService $attribute, ProductCustomAttributeService $customAttribute, ProductVolumeDiscountService $volumeDiscount, ProductDimensionAttributeService $dimension, ProductWeightAttributeService $weight)
      {
          $this-&gt;productRepo = $productRepo;
          $this-&gt;entityDescription = $entityDescription;
          $this-&gt;entitySeo = $entitySeo;
          $this-&gt;entitySlug = $entitySlug;
          $this-&gt;tax = $tax;
          $this-&gt;attribute = $attribute;
          $this-&gt;customAttribute = $customAttribute;
          $this-&gt;volumeDiscount = $volumeDiscount;
          $this-&gt;dimension = $dimension;
          $this-&gt;weight = $weight;
      }
  `
  </code></pre>
  
  <p>Is it bad practice to have as much arguments passed to the constructor in PHP (please ignore the long names of the services as these might change when the ERP namespaces have been decided upon)?</p>
  
  <p>As answered by Ben below, in this case it is not. My question was not related to OOP but more to performance etc.. The reason being is that this particular class ProductService is what web deves would do with a controller, i.e. they would probably (and against principles) add all DB relationships in one ProductController which handles repository services (db etc..) and attaches relationships and then it suddenly becomes your business logic.</p>
  
  <p>In my application (and I see most applications this way), the web layer is just another layer. MVC takes care of the web layer and sometimes other Apis too but I will not have any logic except related to views and JS frameworks in my MVC. All of this is in my software.</p>
  
  <p>In conclusion: I know that this is a very SOLID design, the dependencies are injected and they really are dependencies (i.e. a product must have tax and a product does have weight etc..) and they can easily be swapped with other classes thanks to the interfaces and ServiceProviders. Now thanks to the answers, I also know that it is Okay to inject so many dependencies in constructor.</p>
  
  <p>I will eventually write an article about the design patterns which I use and why I use them in different scenarios so follow me if you're interested in such.</p>
  
  <p>Thanks everyone</p>