Rationale behind Dependency Injection Container libraries

It’s an implementation detail and there are many solutions. In Maphper I solved this by having each mapper attach child mappers to the entities dynamically so:

$blog->author is an instance of a class which wraps the mapper for authors and is injected on the fly. Take a look at https://github.com/Level-2/Maphper/blob/master/maphper/maphper.php line 105. The wrap function for a one to one relationship will call getdata on https://github.com/Level-2/Maphper/blob/master/maphper/relation/one.php which returns an instance of that class with the mapper already injected.

This allows you to use it like this:

$authorSource = new \Maphper\DataSource\Database($pdo, 'author', 'id');
$authors = new \Maphper\Maphper($authorSource);

$blogSource = new \Maphper\DataSource\Database($pdo, 'blog', 'id');
$blogs = new \Maphper\Maphper($blogSource);


$relation = new \Maphper\Relation\Many($blogs, 'id', 'authorId');
$authors->addRelation('blogs', $relation);


$relation = new \Maphper\Relation\One($authors, 'authorId', 'id');
$blogs->addRelation('author', $relation);

And once it’s set up, it’s managed internally and transparently so you can call:

foreach ($author->blogs as $blog) {
}

//or

echo $blog->author->name;

And it just works without needing to inject extra dependencies. Imho this is the cleanest way of doing it because none of the dependencies of the mappers are known outside the top level where they’re configured.

if you wanted to you could do this:

$author = $blog->author->blogs->item(0)->author->blogs->item(1)->author;

Which is a bit pointless, but more useful when you have:


$order->customer->address->address1;