acelot/resolver

View on GitHub
README.md

Summary

Maintainability
Test Coverage
# Resolver

[![Build Status](https://travis-ci.org/acelot/resolver.svg?branch=master)](https://travis-ci.org/acelot/resolver)
[![Code Climate](https://img.shields.io/codeclimate/coverage/acelot/resolver.svg)](https://codeclimate.com/github/acelot/resolver)
![](https://img.shields.io/badge/dependencies-zero-blue.svg)
![](https://img.shields.io/badge/license-MIT-green.svg)

**Resolver** is a dependency auto resolver for PHP 7 and 8. Supports PSR-11 `ContainerInterface`.

### Installation

```
composer require acelot/resolver
```

### Why?

Imagine that you have a controller:

```php
class UsersController
{
    public function __construct(UsersService $service)
    {
        // ...
    }
}
```

As you can see the controller requires `UsersService` in constructor. To resolve this dependency you can just pass
the new instance of `UsersService`. Let's do this:

```php
$service = new UsersService();
$controller = new UsersController($service);
```

It doesn't work, because `UsersService`, in turn, requires `UsersRepository` to access the data.

```php
class UsersService
{
    public function __construct(UsersRepository $repository)
    {
        // ...
    }
}
```

Okay, let's create the repository instance!

```php
$repository = new UsersRepository();
$service = new UsersService($repository);
$controller = new UsersController($service);
```

Sadly, it still doesn't work, because we encountering the new dependency! The repository, surprisingly, requires
a database connection :)

```php
class UsersRepository
{
    public function __construct(Database $db)
    {
        // ...
    }
}
```

You say "Eat this!".

```php
$db = new Database('connection string here');
$repository = new UsersRepository($db);
$service = new UsersService($repository);
$controller = new UsersController($service);
```

Success! We have finally created the instance of `UsersController`!
Now imagine that you have ten or hundred controllers like this?!
With **Resolver** you can greatly simplify creation of classes.
In what turns this code using **Resolver**:

```php
$resolver = new Resolver([
    Database::class => ObjectDefinition::define(Database::class)->withArgument('connectionString', 'connection string here')
]);

$controller = $resolver->resolve(UsersController::class);
```

And it's all.


### How it works?

**Resolver** resolves the classes by using [Reflection](http://php.net/manual/ru/book.reflection.php).
Through reflection the **Resolver** finds out all dependencies of the class and all dependencies of
dependencies and so on. When **Resolver** reaches the deepest dependency it starts creating instances
of these one by one until the top class. The resolved classes are stored in local array to avoid re-resolving.

### Available definitions

- FactoryDefinition (short alias `factory()`)
- ObjectDefinition (short alias `object()`)
- ValueDefinition (short alias `value()`)

### Instance sharing

Resolved definitions can be shared between calls via `->shared()` method. This method available in `FactoryDefinition` and `ObjectDefinition`. `ValueDefinition` is shared always by design.

---

**Resolver** (c) by Valeriy Protopopov.

**Resolver** is licensed under a MIT license.