bitExpert / disco

PSR-11 compatible Dependency Injection Container for PHP.
Apache License 2.0
139 stars 17 forks source link

[Feature] Disco should be able to autowire bean instances #79

Open shochdoerfer opened 7 years ago

shochdoerfer commented 7 years ago

As discussed with @Ocramius today it would make sense for Disco to be able to support autowiring for bean instances to reduce the amount of configuration code needed and to be able to get rid of traits for structuring the configuration code.

The following configuration:

/** @Bean */
protected function database() : Database
{
    return new Database('mysql://user:secret@localhost/mydb');
}

/** @Bean */
public function productService() : ProductService
{
    return new ProductService($this->database());
}

could then be simplified like this:

/** @Bean */
protected function database() : Database
{
    return new Database('mysql://user:secret@localhost/mydb');
}

/** @Bean */
abstract public function productService() : ProductService;

At a later stage we could move the methods into separate interfaces - to be able to get rid of the abstract keyword and ultimately get rid of the trait approach.

A few problems need to be solved:

shochdoerfer commented 7 years ago

Just a quick thought: As for primitive value injection we could potentially do some name matching with the parameters injected to the bean configuration method.

Ocramius commented 7 years ago

Didn't have much time to work on this, but I'm currently building Roave/DependencyResolver (currently private).

The idea is to have following:

  1. analyze existing code
  2. build complete dependency graph (find constructors, setters, etc)
  3. run "compiler passes" on the dependency graph (allows replacing dependencies, providing dependencies for when none could be resolved, etc)
  4. select dependencies (we don't need everything)
  5. run further compiler passes to define which ones are consumer-exposed dependencies, and which ones are just private dependencies (services to never be exposed by the container directly)
  6. generate factory code (container-specific, in this case - this is not part of Roave/DependencyResolver)

What you'd do is probably expose a CLI script to generate factory snippets to be copied in the container. What you will get from Roave/DependencyResolver is a framework-agnostic dependency graph that you can traverse and modify.

shochdoerfer commented 7 years ago

Instead of sprinkling annotations in the whole code base to configure setter injection, named injection etc. we could simply add those annotations to the bean configuration method.