PHPackages                             talesoft/tale-di - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. talesoft/tale-di

ActiveLibrary

talesoft/tale-di
================

A PSR-15 compatible HTTP utility library

0.1.1(9y ago)0163MITPHPPHP &gt;=7.0.8

Since May 21Pushed 6y ago3 watchersCompare

[ Source](https://github.com/Talesoft/tale-di)[ Packagist](https://packagist.org/packages/talesoft/tale-di)[ Docs](http://docs.talesoft.io/tale-framework/tale/di)[ RSS](/packages/talesoft-tale-di/feed)WikiDiscussions master Synced today

READMEChangelog (2)Dependencies (1)Versions (2)Used By (0)

[![Packagist](https://camo.githubusercontent.com/4424b1740fce8ccb7e89a161dc96beaad92abaab6c0196252f11f71ca2682403/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f74616c65736f66742f74616c652d64692e7376673f7374796c653d666f722d7468652d6261646765)](https://packagist.org/packages/talesoft/tale-di)[![License](https://camo.githubusercontent.com/216fb1003a3b72e33b86707ade8cd367ecd2bfa2bba8af17f3a727d598811833/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f54616c65736f66742f74616c652d64692e7376673f7374796c653d666f722d7468652d6261646765)](https://github.com/Talesoft/tale-di/blob/master/LICENSE.md)[![CI](https://camo.githubusercontent.com/ff02ff1d7e97b71969802c30103a85375616cdb598e2702e694c2d2f45653f0c/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f54616c65736f66742f74616c652d64692e7376673f7374796c653d666f722d7468652d6261646765)](https://travis-ci.org/Talesoft/tale-di)[![Coverage](https://camo.githubusercontent.com/392a5b819f2a64c138c85eda9467f27f22f3f7ee9c4a216b34a67848f9e58416/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636c696d6174652f636f7665726167652f54616c65736f66742f74616c652d64692e7376673f7374796c653d666f722d7468652d6261646765)](https://codeclimate.com/github/Talesoft/tale-di)

Tale DI
=======

[](#tale-di)

What is Tale DI?
----------------

[](#what-is-tale-di)

Tale DI is a lightweight implementation of the PSR-11 Dependency Injection spec will full auto-wiring support.

The API might still change here and there.

Installation
------------

[](#installation)

```
composer req talesoft/tale-di
```

Usage
-----

[](#usage)

### ContainerBuilder

[](#containerbuilder)

`use Tale\Di\ContainerBuilder;`

Using the ContainerBuilder, you can auto-wire a fully working DI container including full PSR-6 cache support.

The container returned will be a `Tale\Di\Container` which is explained below.

```
$cachePool = new RedisCachePool();

$builder = new ContainerBuilder($cachePool);

$builder->add(ViewRenderer::class);

$builder->add(ControllerDispatcher::class);

$builder->addInstance(new PDO(...));

$container = $builder->build();

$pdo = $container->get(PDO::class);
```

### Service Locators

[](#service-locators)

```
use Tale\Di\ServiceLocator\FileServiceLocator;
use Tale\Di\ServiceLocator\DirectoryServiceLocator;
use Tale\Di\ServiceLocator\GlobServiceLocator;

```

If you don't want to add every single file manually, you can also use one of the three service Locators that come with Tale DI.

```
$builder->addLocator(
    new FileServiceLocator('src/Classes/MyClass.php')
);

$builder->addLocator(
    new DirectoryServiceLocator('../src')
);

$builder->addLocator(
    new GlobServiceLocator('../src/{Controller,Model}/**/*.php')
);

$container = $builder->build();
```

### Injections and philosophy

[](#injections-and-philosophy)

Tale DI, by design, only allows constructor injections. There are no optional dependencies that are not covered in a constructor and there are no `XyzAware` interfaces and no possibility to do it.

This avoids a lot of magic and defensive null checks all over your code. If this is not what you like, Tale DI might not be what you're looking for. I suggest you give it a try anyways.

Injections happen simply by class name or an interface it implements:

```
class OrderProvider
{
    public function __construct(OrderRepository $repository)
}

$orderProvider = $container->get(OrderProvider::class);
```

It doesn't matter if you ever added the dependency to the container, it will auto-wire any external (or internal) dependency that has a readable type (and even that can be handled). This is possible because Tale DI works solely based on PHPs existing class mechanisms, interfaces and reflection.

```
interface ViewRendererInterface
{
}

class ViewRenderer implements ViewRendererInterface
{
}

//...

$renderer = $container->get(ViewRendererInterface::class);
// $renderer is instanceof ViewRenderer
```

Optional dependencies work as expected and should be defaulted to default/null implementations so no defensive null checks are required.

```
class AvatarGenerator
{
    /**
     * @var CacheInterface
     */
    private $cache;

    public function __construct(CacheInterface $cache = null)
    {
        $this->cache = $cache ?? new RuntimeCache();
    }
}
```

### Iterables and Arrays of interfaces

[](#iterables-and-arrays-of-interfaces)

Tale DI has a notion of **Tags** specified through plain PHP interfaces. You can inject by using interfaces:

```
class EntityManager
{
    public function __construct(DbalInterface $dbal)
}
```

and through proper type-hinting in the doc-comment you can even inject all instances of a specific interface:

```
class Importer
{
    /**
     * @param iterable
     */
    public function __construct(iterable $workers)
    {
        foreach ($workers as $worker) {
            $this->initializeWorker($worker);
        }
    }

    /**
     * @param array
     */
    public function __construct(array $workers)
    {
        $this->workers = array_filter($workers, fn($worker) => $worker->canImport());
    }
}
```

This will inject all known dependencies of type WorkerInterface into the `workers` argument.

### Parameters

[](#parameters)

Tale DI can't only inject classes and instances, you can specify fixed parameters that are injected based on their names. Notice they should be serializable to make use of the caching mechanisms.

```
$builder->setParameter('someParameter', 'some value');

//Any class with a parameter 'someParameter' will get 'some value' injected as a string
```

The second parameter allows you to reduce the parameter to be used on a specific class or interface only.

This also allows creating instances of external types without requiring a specific factory for it:

```
class UserManager
{
    public function __construct(PDO $pdo)
    {
        $this->pdo = $pdo; // Fully working PDO instance!
    }
}

$builder->setParameters([
    // These are the parameter names PDO internally uses in its constructor!
    'dsn' => 'mysql:host=localhost',
    'username' => 'root',
    'passwd' => '',
    'options' => [PDO::ATTR_ERRMODE => PDO_ERRMODE_EXCEPTION]
], PDO::class);

$builder->add(UserManager::class);
$container = $builder->build();

$userManager = $container->get(UserManager::class);
// PDO will be fully wired in UserManager
```

### Manually construct container

[](#manually-construct-container)

The base setup of the container is pretty simple. Most of the stuff is used for the auto-wiring mechanism, but you can also completely avoid the `ContainerBuilder` and use containers directly.

Tale DI brings three base containers with it that you can use for their specific purposes.

#### Container

[](#container)

`use Tale\Container;`

The Tale Container and the heart of the DI system is a container that resolves values through specific `Tale\Di\DependencyInterface`instances. This is how it works:

```
$dependencies = [
    //Value Dependency is just a value. Can be any kind of value.
    'test value' => new ValueDependency('some value'),

    //A reference dependency references another value in the container
    'reference' => new ReferenceDependency('test value'),

    //A callback dependency only gets resolved when it's requested
    'factory' => new CallbackDependency(function (ContainerInterface $container) {
        return new Something($container->get(SomethingElse::class));
    }),

    //Same as CallbackDependency, but will cache the result between each ->get() call
    'lazy factory' => new PersistentCallbackDependency(function () {
        return (new SomeHeavyWorker())->getResult();
    })
];

$container = new Container($dependencies);

$container->get('test value'); //"some value"
$container->get('reference'); //"some value"
// etc.
```

You can always define own dependency types and how they are resolved by implementing `Tale\Di\DependencyInterface`:

```
final class PdoDependency implements DependencyInterface
{
    private $pdo;

    public function __construct()
    {
        $this->pdo = new PDO(...);
    }

    public function get(ContainerInterface $container)
    {
        return $this->pdo;
    }
}

$container = new Container(['pdo' => new PdoDependency()]);
$pdo = $container->get('pdo');

$stmt = $pdo->prepare(...);
```

#### ArrayContainer

[](#arraycontainer)

`use Tale\Di\Container\ArrayContainer;`

Mostly useful for testing, this is a really basic implementation of PSR-11 that just maps fixed names to values

```
$container = new ArrayContainer([
    SomeClass::class => new SomeClass(),
    'test key' => 15
]);

$container->get(SomeClass::class); //SomeClass instance
$container->get('test key'); //15
```

#### NullContainer

[](#nullcontainer)

`use Tale\Di\Container\NullContainer;`

A Null Container that always returns false when calling `->has()` and always throws a `NotFoundException` when calling `->get()`.

This is mostly useful as a default container for classes that want to decorate containers as an optional dependency and require a default implementation to avoid defensive null checks.

```
final class AdapterFactory
{
    public function __construct(ContainerInterface $container = null)
    {
        $this->container = $container ?? new NullContainer();
    }

    public function createAdapter(): AdapterInterface
    {
        $adapter = null;
        if ($this->container->has(SomeAdapter::class)) {
            $adapter = $this->container->get(SomeAdapter::class);
        } else if ($this->container->has(SomeOtherAdapter::class)) {
            $adapter = $this->container->get(SomeOtherAdapter::class);
        } else {
            $adapter = new SomeDefaultAdapter();
        }
        return $adapter;
    }
}
```

### Type Information

[](#type-information)

`use Tale\Di\TypeInfoFactory\PersistentTypeInfoFactory;`

Notice this will probably end up in an own library at some point.

```
$typeInfoFactory = new PersistentTypeInfoFactory();

$typeInfo = $typeInfoFactory->get('array');

$typeInfo->isGeneric() //true

$typeInfo->getGenericType()->getName() //array

$typeInfo->getGenericTypeParameters()[0]->getName() //int
```

### Parameter Reader

[](#parameter-reader)

`use Tale\Di\ParameterReader\DocCommentParameterReader;`

A parameter reader that also takes into account doc comment `@param`-annotations

```
$typeInfoFactory = new PersistentTypeInfoFactory();

$paramReader = new DocCommentParameterReader($typeInfoFactory);

$reflClass = new ReflectionClass(SomeClass::class);

$params = $paramReader->read($reflClass->getMethod('__construct');

var_dump($params);
```

###  Health Score

24

—

LowBetter than 35% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity10

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~268 days

Total

2

Last Release

3323d ago

PHP version history (2 changes)0.1PHP &gt;=5.5.0

0.1.1PHP &gt;=7.0.8

### Community

Maintainers

![](https://www.gravatar.com/avatar/75a80e0830e63c723808d021d3a1648a2643db60f4ac2e40842da05f227f956b?d=identicon)[TorbenKoehn](/maintainers/TorbenKoehn)

---

Top Contributors

[![TorbenKoehn](https://avatars.githubusercontent.com/u/1403556?v=4)](https://github.com/TorbenKoehn "TorbenKoehn (21 commits)")

---

Tags

dependency-injectiondidependencies

### Embed Badge

![Health badge](/badges/talesoft-tale-di/health.svg)

```
[![Health](https://phpackages.com/badges/talesoft-tale-di/health.svg)](https://phpackages.com/packages/talesoft-tale-di)
```

###  Alternatives

[php-di/php-di

The dependency injection container for humans

2.8k47.0M865](/packages/php-di-php-di)[laminas/laminas-servicemanager

Factory-Driven Dependency Injection Container

15954.0M637](/packages/laminas-laminas-servicemanager)[aura/di

A serializable dependency injection container with constructor and setter injection, interface and trait awareness, configuration inheritance, and much more.

357963.4k49](/packages/aura-di)[mrclay/props-dic

Props is a simple DI container that allows retrieving values via custom property and method names

3611.3M1](/packages/mrclay-props-dic)[slince/di

A flexible dependency injection container

20256.7k5](/packages/slince-di)[joomla/di

Joomla DI Package

15375.0k10](/packages/joomla-di)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
