Reputation: 309
I am learning Auraphp Di, and I want to write sample code. Suppose I have these files:
public/index.php:
use Aura\Di\ContainerBuilder;
use MyPackage\Component\Authentication\AuthenticateFlow;
require_once dirname(__DIR__) . '/vendor/autoload.php';
$builder = new ContainerBuilder();
$di = $builder->newInstance();
$di->set('authenticateFlow', $di->lazyNew(AuthenticateFlow::class));
$authenticateFlow = $di->get('authenticateFlow');
$authenticateFlow->showName('Belkin');
/src/Components/Authentication/AuthenticationFlow.php:
namespace MyPackage\Components\Authentication;
class AuthenticationFlow
{
public function showName($name)
{
echo $name;
}
}
This is working fine. Now suppose I have another class (/src/Components/Authentication/Filter.php), which has a method called filterInput:
namespace MyPackage\Components\Authentication;
class Filter
{
public function filterInput($input)
{
return htmlspecialchars($input);
}
}
How can I inject Filter to AuthenticationFlow, to use filterInput() method? I wanna have something like this in AuthenticationFlow::showName():
echo $this->filter->filterInput($name);
I am aware that I need to inject Filter class in AuthenticationFlow constructor, but I don't know if I can use the container built in the index.php or not. If I need to create another container in AuthenticationFlow, how index.php would be aware of it?
Upvotes: 1
Views: 510
Reputation: 4244
Your application need to make use of the di container heavily in-order to inject the necessary dependencies. This is not the case of Aura.
Let us step back and look what you would do if you don't use a container.
In-order to make use of Filter
object inside AuthenticationFlow
, you need to inject the Filter
object either via constructor or a setter method. In the example below I am making use of constructor injection.
class AuthenticationFlow
{
protected $filter;
public function __construct(Filter $filter)
{
$this->filter = $filter;
}
public function showName($name)
{
return $this->filter->filterInput($name);
}
}
So you will create an object of AuthenticationFlow
as below.
$auth = new AuthenticationFlow(new Filter);
In the case of Aura.Di, you may do something like
$object = $di->newInstance(AuthenticateFlow::class);
If auto resolution is turned off, you need to define dependencies as below
$di->params[AuthenticateFlow::class]['filter'] = $di->lazyNew(Filter::class);
This will not be true, in an application. You may need AuthenticateFlow
on a different HelloController::class
.
Class HelloController
{
protected $auth;
public function __construct(AuthenticationFlow $auth)
{
$this->auth = $auth;
}
public function execute()
{
// Do something
}
}
So in that case, HelloController::class
need to be instantiated via the di itself. Else the dependencies will not be injected automatically.
$object = $di->newInstance(HelloController::class);
You can extend the Aura\Di\ContainerConfig
and define services in multiple classes.
Example :
namespace YourVendor;
use Aura\Di\Container;
use Aura\Di\ContainerConfig;
class Config extends ContainerConfig
{
public function define(Container $di)
{
$di->set(HelloController::class, $di->lazyNew(HelloController::class));
$di->params[HelloController::class]['auth'] = $di->lazyNew(AuthenticateFlow::class);
$di->params[AuthenticateFlow::class]['filter'] = $di->lazyNew(Filter::class);
}
public function modify(Container $di)
{
// You can get the service and modify if needed
// $auth = $di->get('authenticateFlow');
}
}
Now your index.php will look like,
require_once dirname(__DIR__) . '/vendor/autoload.php';
$builder = new ContainerBuilder();
$di = $container_builder->newConfiguredInstance([
'YourVendor\Config',
]);
$hello = $di->newInstance(HelloController::class);
$hello->execute();
As I mentioned in previous answer, I recommend you go through the docs first. It will really help you in long run.
Upvotes: 2