Explanation
To pass parameters to contructors you may use the direct injection mechanism in Magento2 (look for di.xml).
Defining an argument in a class constructor in Magento 2 is very similar to Magento 1 Mage::getSingleton method. You will get a singleton class of the type you required in the constructor.
Magento will just pass you a singleton instance of the object you required in the constructor by using a reflection mechanism.
If you declare a parameter of type \Magento\Customer\Model\Session you will automatically get that class as singleton.
Just like doing Mage::getSingleton('customer/session') in Magento 1.
If you need to pass arguments you problably need to use a Factory. Using a factory is like the Mage::getModel in Magento 1.
Factories are automatically created by Magento 2 framework, you do not need to define them unless you really need. Just add Factory to your class name.
In you example I see you use \Magento\Sales\Model\OrderFactory. That class is a factory for \Magento\Sales\Model\Order and you can use it do instantiate orders like Mage::getModel('sales/order') in Magento 1.
If you need to pass arguments to a factory constructor you just have to pass them to create method with an hash.
For example:
$this->myObjectFactory->create(['myparam' => $myvalue]);
This will create a new object and will pass $myvalue to the constructor argument called $myparam. No matter of its position.
Example 1: You need to access customer session in your class
<?php
namespace MyNS\MyModule\Model;
class MyClass {
protected $customerSession;
public function __construct(
\Magento\Customer\Model\Session $customerSession
) {
$this->customerSession = $customerSession;
}
public function getCustomerSession() {
return $this->customerSession;
}
}
In the previous example, an instance of \Magento\Customer\Model\Session is "automatically" passed to $customerSession parameter. Magento just detects you are asking for that class in your constructor and it will pass you an instance of such object.
This is an equivalend of: Mage::getSingleton('customer/session') in Magento 1.
Have a look here to understand how it does: Magento\Framework\ObjectManager\Factory\AbstractFactory
Example 2: You need to load an order information
<?php
namespace MyNS\MyModule\Model;
class MyClass {
protected $orderInterfaceFactory;
public function __construct(
\Magento\Sales\Api\Data\OrderInterfaceFactory $orderInterfaceFactory
) {
$this->orderInterfaceFactory = $orderInterfaceFactory;
}
public function getOrder($orderId) {
$order = $this->orderInterfaceFactory->create();
$order->load($orderId);
return $order;
}
}
In this example you do not need a singleton, you need an order instance.
To achieve this you need to require a Factory Class. A Factory Class is a special class that can create class instances.
This is the equivalent of Mage::getModel('sales/order') in Magento 1.
Factory classes:
Factory classes can be both manually or automatically defined. If you create your own class and you do not create the Factory class, Magento will automatically build it for you.
So, if you create:
<?php
namespace MyNS\MyModule\Model;
class MyClass {
public function myMethod() { return "foo"; }
}
and you need to access to and instance of it, you can just ask for MyClassFactory, even if you did not define such class:
<?php
namespace MyNS\MyModule\Model;
class MyOtherClass {
protected $myClassFactory;
public function __construct(
MyClassFactory $myClassFactory
) {
$this->myClassFactory = $myClassFactory;
}
public function myOtherMethod() {
$myClassInstance = $this->myClassFactory->create();
$myClassInstance->myMethod();
}
}
Interfaces and preferences
In Magento2, when you ask for a class direct injection, is recommended to ask for an Interface Class.
In my previous example (Example #2), I do not require an Order class, but and OrderInterface class. This is the best way because interfaces are supposed to be always compatible between Magento different versions.
You question may be: An interface is not a class, how can I instantiate it?
The answer is in the Magento 2 prefernce mechanism (it is the equivalent of the rewrite mechanism in Magento 1).
OrderInterface is mapped to Magento\Sales\Model\Order in di.xml file of magento-sales module:
...
<preference for="Magento\Sales\Api\Data\OrderInterface" type="Magento\Sales\Model\Order"/>
...
So, when you ask for OrderInterface, Magento will give you an instance of Magento\Sales\Model\Order.
If your module need to rewrite Magento\Sales\Model\Order, you can define your new preference pointing to another class. This new class MUST implement OrderInterface.
This allows a perfect integration between modules.