1

I'm looking for idea to make a DI container that can store multiple instances of the same object. Usually, a DI container should store either a single instance of the object, or create new object each time it gets requested. Here's example I'm working on:

class Container {
    protected $store;

    public function get($alias) {
         if (isset($this -> store[$alias])) {
             return $this -> store[$alias]($this);
         }
    }

    public function bind($alias, Closure $obj) {
         $this -> store[$alias] = $obj;
    }
}

This all works well, for this case:

$c = new Container();
$c -> bind('book', function() {
    return new Book();
});

$book = $c -> get('book');

Now imagine I have class "Catalog", which behavior is dictated by parameters passed to it's constructor:

class Catalog {
    protected $category;

    public function __construct($category) {
        $this -> category = $category;    
    }
}

I want only single instance of each category stored in container. Yes i can do this easily by

$c -> bind('catalog.magazines', function() {
    return new Catalog('magazines');
});

$c -> bind('catalog.books', function() {
    return new Catalog('books');
});

But categories can be dynamically created at runtime, and this seems like a lot of code. Is there a convenient solution for this? Only one instance of each object and can handle them dynamically. Or maybe it's not DI at all?

  • I think you're talking about lazy initialization. DI containers I know of do that by default. See PHP-DI (lazy injection), Symfony DI (lazy services) – scriptin Apr 15 '15 at 5:59
  • If these objects can be created at runtime then you're talking about value objects (you can't create behaviour) and you don't need DI for them. DI is dealing with abstract dependencies. Catalog(Books) and Catalog(Magazines) will always be objects of the same class and if they collaborate with some value objects they shouldn't really need them to be instantiated and fully operational in abstract sense ($catalog->giveMeSomethingToRead() may return false). – shudder Apr 18 '15 at 14:24
1

But categories can be dynamically created at runtime, and this seems like a lot of code. Is there a convenient solution for this? Only one instance of each object and can handle them dynamically. Or maybe it's not DI at all?

Well, if categories can be dynamically created, how are you going to identify and get from DI container?

I think you should not put categories /catalogs / whatever into container if they are really mass-created at runtime dynamically. Instead you might want to put CategoryCollection into container and add / query / remove collections from it using any criteria you want.

Isn't that what you want?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.