Why does adding constructor parameters require my to clear /generated












4















I'm using Magento 2.2 in development mode.



I have a controller class



class MyController
{
public function __construct(
MagentoFrameworkAppActionContext $context,
MagentoFrameworkMessageManagerInterface $messageManager)
{
// stuff
}
}


That works correctly. However, if I add an additional constructor parameter like this:



class MyController
{
public function __construct(
MagentoFrameworkAppActionContext $context,
MagentoFrameworkViewResultPageFactory $resultPageFactory,
MagentoFrameworkMessageManagerInterface $messageManager)
{
// stuff
}
}


I get the error



PHP Fatal error: Uncaught TypeError: Argument 2 passed to
BenTestingControllerTest::__construct() must be an instance of
MagentoFrameworkViewResultPageFactory, instance of
MagentoFrameworkMessageManagerInterface given, called in
/magento-dev/magento2/generated/code/Ben/Testing/Controller/Test/Interceptor.php
on line 7 and defined in /magento-dev/magento2/app/code/Ben/Testing/Controller/Test.php:7
...


If I clear the /generated folder and refresh the page, it works.



My question is about how Magento handles caching and generated code. I can add additional code to non-constructor functions without needing to clear /generated, and it works. Why does that work, but adding additional constructor parameters requires me to clear the /generated folder?










share|improve this question



























    4















    I'm using Magento 2.2 in development mode.



    I have a controller class



    class MyController
    {
    public function __construct(
    MagentoFrameworkAppActionContext $context,
    MagentoFrameworkMessageManagerInterface $messageManager)
    {
    // stuff
    }
    }


    That works correctly. However, if I add an additional constructor parameter like this:



    class MyController
    {
    public function __construct(
    MagentoFrameworkAppActionContext $context,
    MagentoFrameworkViewResultPageFactory $resultPageFactory,
    MagentoFrameworkMessageManagerInterface $messageManager)
    {
    // stuff
    }
    }


    I get the error



    PHP Fatal error: Uncaught TypeError: Argument 2 passed to
    BenTestingControllerTest::__construct() must be an instance of
    MagentoFrameworkViewResultPageFactory, instance of
    MagentoFrameworkMessageManagerInterface given, called in
    /magento-dev/magento2/generated/code/Ben/Testing/Controller/Test/Interceptor.php
    on line 7 and defined in /magento-dev/magento2/app/code/Ben/Testing/Controller/Test.php:7
    ...


    If I clear the /generated folder and refresh the page, it works.



    My question is about how Magento handles caching and generated code. I can add additional code to non-constructor functions without needing to clear /generated, and it works. Why does that work, but adding additional constructor parameters requires me to clear the /generated folder?










    share|improve this question

























      4












      4








      4








      I'm using Magento 2.2 in development mode.



      I have a controller class



      class MyController
      {
      public function __construct(
      MagentoFrameworkAppActionContext $context,
      MagentoFrameworkMessageManagerInterface $messageManager)
      {
      // stuff
      }
      }


      That works correctly. However, if I add an additional constructor parameter like this:



      class MyController
      {
      public function __construct(
      MagentoFrameworkAppActionContext $context,
      MagentoFrameworkViewResultPageFactory $resultPageFactory,
      MagentoFrameworkMessageManagerInterface $messageManager)
      {
      // stuff
      }
      }


      I get the error



      PHP Fatal error: Uncaught TypeError: Argument 2 passed to
      BenTestingControllerTest::__construct() must be an instance of
      MagentoFrameworkViewResultPageFactory, instance of
      MagentoFrameworkMessageManagerInterface given, called in
      /magento-dev/magento2/generated/code/Ben/Testing/Controller/Test/Interceptor.php
      on line 7 and defined in /magento-dev/magento2/app/code/Ben/Testing/Controller/Test.php:7
      ...


      If I clear the /generated folder and refresh the page, it works.



      My question is about how Magento handles caching and generated code. I can add additional code to non-constructor functions without needing to clear /generated, and it works. Why does that work, but adding additional constructor parameters requires me to clear the /generated folder?










      share|improve this question














      I'm using Magento 2.2 in development mode.



      I have a controller class



      class MyController
      {
      public function __construct(
      MagentoFrameworkAppActionContext $context,
      MagentoFrameworkMessageManagerInterface $messageManager)
      {
      // stuff
      }
      }


      That works correctly. However, if I add an additional constructor parameter like this:



      class MyController
      {
      public function __construct(
      MagentoFrameworkAppActionContext $context,
      MagentoFrameworkViewResultPageFactory $resultPageFactory,
      MagentoFrameworkMessageManagerInterface $messageManager)
      {
      // stuff
      }
      }


      I get the error



      PHP Fatal error: Uncaught TypeError: Argument 2 passed to
      BenTestingControllerTest::__construct() must be an instance of
      MagentoFrameworkViewResultPageFactory, instance of
      MagentoFrameworkMessageManagerInterface given, called in
      /magento-dev/magento2/generated/code/Ben/Testing/Controller/Test/Interceptor.php
      on line 7 and defined in /magento-dev/magento2/app/code/Ben/Testing/Controller/Test.php:7
      ...


      If I clear the /generated folder and refresh the page, it works.



      My question is about how Magento handles caching and generated code. I can add additional code to non-constructor functions without needing to clear /generated, and it works. Why does that work, but adding additional constructor parameters requires me to clear the /generated folder?







      magento2 php






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked 12 hours ago









      Ben RubinBen Rubin

      1235




      1235






















          1 Answer
          1






          active

          oldest

          votes


















          5














          Short answer: Because Magento does not use the class you think it uses.

          Long answer:

          It is because of plugins/interceptors.

          So, for every class that has methods that has plugins, magento generates a class with the same name as the original class and adds Interceptor at the end.

          You can see that in your error message.

          This interceptors extend the original classes



          use MagentoFrameworkInterceptionInterceptor;

          public function __construct(list of main class parameters in here)
          {
          $this->___init();
          parent::__construct(list of main class parameters in here); //THIS LINE IS IMPORTANT FOR YOUR PROBLEM.
          }

          /**
          * {@inheritdoc}
          * This is added for every interceptable method in the main class and it's named exactly like the method
          */
          public function interceptableMethod(parameters of interceptable method)
          {
          $pluginInfo = $this->pluginList->getNext($this->subjectType, 'interceptableMethod');
          if (!$pluginInfo) {
          return parent::interceptableMethod(parameters of interceptable method);
          } else {
          return $this->___callPlugins('interceptableMethod', func_get_args(), $pluginInfo);
          }
          }


          The second thing to take into account is that such an interceptor class is generated only if it does not exist already.



          So when you change the constructor signature of your class and the interceptor class will be generated this happens.



          Your new class constructor will require 3 parameters.

          The generated interceptor still has the old constructor with 2 parameters.

          This is not a problem for the interceptor class itself as it will be instantiated with 2 dependencies.

          But then it calls parent::__construct (the line I marked in the example above) with the same 2 parameters. and parent is your own class that now requires 3 parameters.

          So this will trigger an error.

          Removing the interceptor class from the generated folder makes magento regenerate it on the next call and this time it will have the proper constructor signature.






          share|improve this answer
























          • Great explanation. Thank you for your help.

            – Ben Rubin
            10 hours ago











          Your Answer








          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "479"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmagento.stackexchange.com%2fquestions%2f258382%2fwhy-does-adding-constructor-parameters-require-my-to-clear-generated%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          5














          Short answer: Because Magento does not use the class you think it uses.

          Long answer:

          It is because of plugins/interceptors.

          So, for every class that has methods that has plugins, magento generates a class with the same name as the original class and adds Interceptor at the end.

          You can see that in your error message.

          This interceptors extend the original classes



          use MagentoFrameworkInterceptionInterceptor;

          public function __construct(list of main class parameters in here)
          {
          $this->___init();
          parent::__construct(list of main class parameters in here); //THIS LINE IS IMPORTANT FOR YOUR PROBLEM.
          }

          /**
          * {@inheritdoc}
          * This is added for every interceptable method in the main class and it's named exactly like the method
          */
          public function interceptableMethod(parameters of interceptable method)
          {
          $pluginInfo = $this->pluginList->getNext($this->subjectType, 'interceptableMethod');
          if (!$pluginInfo) {
          return parent::interceptableMethod(parameters of interceptable method);
          } else {
          return $this->___callPlugins('interceptableMethod', func_get_args(), $pluginInfo);
          }
          }


          The second thing to take into account is that such an interceptor class is generated only if it does not exist already.



          So when you change the constructor signature of your class and the interceptor class will be generated this happens.



          Your new class constructor will require 3 parameters.

          The generated interceptor still has the old constructor with 2 parameters.

          This is not a problem for the interceptor class itself as it will be instantiated with 2 dependencies.

          But then it calls parent::__construct (the line I marked in the example above) with the same 2 parameters. and parent is your own class that now requires 3 parameters.

          So this will trigger an error.

          Removing the interceptor class from the generated folder makes magento regenerate it on the next call and this time it will have the proper constructor signature.






          share|improve this answer
























          • Great explanation. Thank you for your help.

            – Ben Rubin
            10 hours ago
















          5














          Short answer: Because Magento does not use the class you think it uses.

          Long answer:

          It is because of plugins/interceptors.

          So, for every class that has methods that has plugins, magento generates a class with the same name as the original class and adds Interceptor at the end.

          You can see that in your error message.

          This interceptors extend the original classes



          use MagentoFrameworkInterceptionInterceptor;

          public function __construct(list of main class parameters in here)
          {
          $this->___init();
          parent::__construct(list of main class parameters in here); //THIS LINE IS IMPORTANT FOR YOUR PROBLEM.
          }

          /**
          * {@inheritdoc}
          * This is added for every interceptable method in the main class and it's named exactly like the method
          */
          public function interceptableMethod(parameters of interceptable method)
          {
          $pluginInfo = $this->pluginList->getNext($this->subjectType, 'interceptableMethod');
          if (!$pluginInfo) {
          return parent::interceptableMethod(parameters of interceptable method);
          } else {
          return $this->___callPlugins('interceptableMethod', func_get_args(), $pluginInfo);
          }
          }


          The second thing to take into account is that such an interceptor class is generated only if it does not exist already.



          So when you change the constructor signature of your class and the interceptor class will be generated this happens.



          Your new class constructor will require 3 parameters.

          The generated interceptor still has the old constructor with 2 parameters.

          This is not a problem for the interceptor class itself as it will be instantiated with 2 dependencies.

          But then it calls parent::__construct (the line I marked in the example above) with the same 2 parameters. and parent is your own class that now requires 3 parameters.

          So this will trigger an error.

          Removing the interceptor class from the generated folder makes magento regenerate it on the next call and this time it will have the proper constructor signature.






          share|improve this answer
























          • Great explanation. Thank you for your help.

            – Ben Rubin
            10 hours ago














          5












          5








          5







          Short answer: Because Magento does not use the class you think it uses.

          Long answer:

          It is because of plugins/interceptors.

          So, for every class that has methods that has plugins, magento generates a class with the same name as the original class and adds Interceptor at the end.

          You can see that in your error message.

          This interceptors extend the original classes



          use MagentoFrameworkInterceptionInterceptor;

          public function __construct(list of main class parameters in here)
          {
          $this->___init();
          parent::__construct(list of main class parameters in here); //THIS LINE IS IMPORTANT FOR YOUR PROBLEM.
          }

          /**
          * {@inheritdoc}
          * This is added for every interceptable method in the main class and it's named exactly like the method
          */
          public function interceptableMethod(parameters of interceptable method)
          {
          $pluginInfo = $this->pluginList->getNext($this->subjectType, 'interceptableMethod');
          if (!$pluginInfo) {
          return parent::interceptableMethod(parameters of interceptable method);
          } else {
          return $this->___callPlugins('interceptableMethod', func_get_args(), $pluginInfo);
          }
          }


          The second thing to take into account is that such an interceptor class is generated only if it does not exist already.



          So when you change the constructor signature of your class and the interceptor class will be generated this happens.



          Your new class constructor will require 3 parameters.

          The generated interceptor still has the old constructor with 2 parameters.

          This is not a problem for the interceptor class itself as it will be instantiated with 2 dependencies.

          But then it calls parent::__construct (the line I marked in the example above) with the same 2 parameters. and parent is your own class that now requires 3 parameters.

          So this will trigger an error.

          Removing the interceptor class from the generated folder makes magento regenerate it on the next call and this time it will have the proper constructor signature.






          share|improve this answer













          Short answer: Because Magento does not use the class you think it uses.

          Long answer:

          It is because of plugins/interceptors.

          So, for every class that has methods that has plugins, magento generates a class with the same name as the original class and adds Interceptor at the end.

          You can see that in your error message.

          This interceptors extend the original classes



          use MagentoFrameworkInterceptionInterceptor;

          public function __construct(list of main class parameters in here)
          {
          $this->___init();
          parent::__construct(list of main class parameters in here); //THIS LINE IS IMPORTANT FOR YOUR PROBLEM.
          }

          /**
          * {@inheritdoc}
          * This is added for every interceptable method in the main class and it's named exactly like the method
          */
          public function interceptableMethod(parameters of interceptable method)
          {
          $pluginInfo = $this->pluginList->getNext($this->subjectType, 'interceptableMethod');
          if (!$pluginInfo) {
          return parent::interceptableMethod(parameters of interceptable method);
          } else {
          return $this->___callPlugins('interceptableMethod', func_get_args(), $pluginInfo);
          }
          }


          The second thing to take into account is that such an interceptor class is generated only if it does not exist already.



          So when you change the constructor signature of your class and the interceptor class will be generated this happens.



          Your new class constructor will require 3 parameters.

          The generated interceptor still has the old constructor with 2 parameters.

          This is not a problem for the interceptor class itself as it will be instantiated with 2 dependencies.

          But then it calls parent::__construct (the line I marked in the example above) with the same 2 parameters. and parent is your own class that now requires 3 parameters.

          So this will trigger an error.

          Removing the interceptor class from the generated folder makes magento regenerate it on the next call and this time it will have the proper constructor signature.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 11 hours ago









          MariusMarius

          164k28312664




          164k28312664













          • Great explanation. Thank you for your help.

            – Ben Rubin
            10 hours ago



















          • Great explanation. Thank you for your help.

            – Ben Rubin
            10 hours ago

















          Great explanation. Thank you for your help.

          – Ben Rubin
          10 hours ago





          Great explanation. Thank you for your help.

          – Ben Rubin
          10 hours ago


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Magento Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmagento.stackexchange.com%2fquestions%2f258382%2fwhy-does-adding-constructor-parameters-require-my-to-clear-generated%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          SQL Server 17 - Attemping to backup to remote NAS but Access is denied

          Always On Availability groups resolving state after failover - Remote harden of transaction...

          Restoring from pg_dump with foreign key constraints