nezamy / di
Dependency Injection and container
v2.0
2020-10-02 06:00 UTC
Requires
- php: >=7.4
- ext-json: *
- ext-mbstring: *
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.16
- phpunit/phpunit: ^7.5 || ^8.5
README
Dependency Injection and container
Installation via composer
composer require nezamy/di
Then load composer autoload
require __DIR__ . '/vendor/autoload.php';
Usage
Let's say we have a Book
class, and we need to call getName
method.
Whatever the method is static or not.
class Book { private string $name = 'First Book'; public function getName(): string { return $this->name; } } $resolver = new Just\DI\Resolver; $resolver->resolve($resolver->prepare([Book::class, 'getName'])); //Or $resolver->resolve([new Book, 'getName']); // the both returns 'First Book'
Maybe you call Book without new
instance you should use prepare
method like the first one.
Call method with parameter
Now we have new method with one parameter
class Book { private string $name = 'First Book'; public function getName(): string { return $this->name; } public function setName(string $name): void { $this->name = $name; } } $container = Just\DI\Container::instance(); $container->setVar('name', 'PHP'); $book = new Book(); $resolver = new Just\DI\Resolver; $resolver->resolve([$book, 'setName']); $book->getName(); // will return 'PHP'
We call th setName
without the parameter, but we set name
in our container above as a global variable.
The resolver will search in the container and if got a variable match the same name of the parameter then pass it, if not will pass null.
Object type parameter & singleton
$function = function(Book $book){ return $book->getName(); }; $container = Container::instance(); $resolver = new Resolver; $name = $resolver->resolve($function); //here $name returns 'First Book' because it's initial value $book = new Book(); $book->setName('Test Book'); // for define a singleton object $container->set(Book::class, $book); $resolver = new Resolver; $name = $resolver->resolve($function); $this->assertSame('Test Book', $name); //$name now is equal 'Test Book'
Call a method in a class has constructor, and the constructor needs two parameters
class User{ private string $name; private string $email; public function __construct(string $name, string $email) { $this->name = $name; $this->email = $email; } public function getName(): string { return $this->name; } public function getEmail(): string { return $this->email; } } $container = Just\DI\Container::instance(); $container->setVar('name', 'Mahmoud Elnezamy'); $container->setVar('email', 'mahmoud@nezamy.com'); $resolver = new Just\DI\Resolver; $name = $resolver->resolve($resolver->prepare([User::class, 'getName'])); // name here will return 'Mahmoud Elnezamy'
Magic Call
class User{ private string $name; private string $email; public function __construct(string $name, string $email) { $this->name = $name; $this->email = $email; } public function getName(): string { return $this->name; } } class Book { public function Auther(User $user){ return $user->getName(); } } $container = Just\DI\Container::instance(); $container->setVar('user', ['Mahmoud', 'email@domain.com']); $container->setMagicCall(User::class, function ($attr, $value){ return new User(...$value); }); $resolver = new Just\DI\Resolver; $book = $resolver->resolve( $resolver->prepare([Book::class, 'Auther']) ); //$book will return 'Mahmoud'
API
$container = \Just\DI\Container::instance(); $container->setVar('name', 'value'); $container->getVar('name'); $container->hasVar('name'); $container->importVars([ 'name' => 'name here', 'id' => '1' ]); $container->set('className', new stdClass()); //Maybe the new instance do some processing or load some configurations or connect with database. //and you won't to make the instance until the first use or call $container->set('className', function (){ return new stdClass(); }); $container->get('className'); $container->has('className'); // define some singleton objects $container->import([ Request::class => new Request(...), Response::class => new Response(...), DB::class => new DB('user', 'pass',...) ]); $container->setMagicCall('UserModel', function ($attr, $value){ if($attr == 'id'){ return new UserModel($value); } return null; }); $container->getMagicCall('UserModel'); $container->hasMagicCall('UserModel');