Add a dependency injector to Sifo

27 views
Skip to first unread message

Eric López

unread,
Dec 29, 2014, 6:01:45 AM12/29/14
to sif...@googlegroups.com
Hi there!

As sifo is going towards a decoupled ecosystem, we should give the option to start using a custom folder structure (one might want to use a src folder with an application in it).
This won't be a problem as composer can handle a custom auto loading process on its own. The problem comes when having a bunch on coexistent independent classes.

Having a decoupled application probably means having an application following SOLID principles. To help with that (with the D in SOLID actually) some kind of dependency injector should be used.
After a while trying some of the dependency injectors out there, the symfony one seems to be the one that suits sifo the best.

Dependencies (services from now on) can either be declared using php, yml or xml. The component automatically checks for circular dependencies, wrong definitions and other stuff. This might seem a performance problem as it's done for each request (and it is) but it also provides the option to pre-compile the services definition in a php class so it can be as fast and optimized as possible.

This does not imply a big change in the whole sifo infrastructure. As for now, I can say this affect:
  • The bootstrap, to load the services in the autoload method.
  • The command line bootstrap for the same reason.
  • The controller to receive an instance of the loader object.

This wouldn't affect existing applications. We'd only be giving access to a new attribute in the controllers.
If you think this can be a boost to sifo I'll start writing code (I already have most of it working properly)!

Cheers, Eric.

Albert Lombarte

unread,
Dec 29, 2014, 10:54:16 AM12/29/14
to sif...@googlegroups.com
Hello Eric,

I buy the dependency injection although I have some concerns on the performance. Could you please elaborate how would you plan to implement it? One thing we tried to do with Sifo is to avoid as much realtime calculations as possible (hence the "regenerate" thing) so I am wondering how would you include this pre-compilation.

Thanks

--
You received this message because you are subscribed to the Google Groups "SIFO, PHP framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sifophp+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Eric López

unread,
Dec 29, 2014, 11:04:23 AM12/29/14
to sif...@googlegroups.com
It would be quite simple actually. The symfony DI provides a feature to compile, optimize and create a plain php class to be used in the services declaration.

In a production environment, this has no overload as the php class would have already been created and committed (think of it as a config file).
In a development environment, this file could be created if the php class doesn't exist yet, using the rebuild or something similar. Yet to decide.

But as I said, the important part: this would have no impact in production as the services would have already been generated.

Cheers!

Eric López

unread,
Dec 30, 2014, 8:44:21 AM12/30/14
to sif...@googlegroups.com
Ok, the whole thing was committed!
This should have no side effects on existing applications unless the config folder of an instance has some really strong write permission denials.

To start using the services definition, one new file should be used ( or two as we gave support to production and development environments ):
  • instance/config/di/services.yml: the file than will contain the production services
  • instance/config/di/services_dev.yml: the file that will contain the development services
None of those files need to exist. If they exist, though, they will be used. The services declaration get compiled into a php file for each request in the development environment and none ( one at most ) in a production environment. At least one file will be automatically created, the instance/config/di/compiled/services.php. That file is the one that will be used in production so yml files don't need to be parsed over and over again. You're strongly encouraged to commit that file.

In the Symfony component page you'll see how to write dependencies files. For now only yml files are supported. Here you have a really really short sneak peak:

// instance/config/di/services_dev.yml
imports:
    - { resource: "services.yml" }

services:
    Guzzle\Http\Client:
        class: Guzzle\Http\Client

    Sifo\Config:
        class: Sifo\Config
        factory: ["Sifo\\Config", getInstance]


Just a final note: if you don't need to inject dependencies or your application is not prepared to do so, just don't do it.
Cheers!

Eric López

unread,
Dec 30, 2014, 8:49:01 AM12/30/14
to sif...@googlegroups.com
I forgot to tell how to use the container itself.
In any controller, 

$sifo_config   = $this->container->get('Sifo\Config');
$guzzle_client = $this->container->get('Guzzle\Http\Client');
Reply all
Reply to author
Forward
0 new messages