We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Module di?

Is there any possibility to inject into di some components at initialization moment? For example: we have ModuleA and ModuleB. ModuleA have some component that must be accesable in ModuleB, is there some possibility?

You can always register services in the DI using a lamda function. For instance:

$di = \Phalcon\DI\FactoryDefault();

$config = $di['config'];
$di['mycomponent'] = function () use ($config) {

    // Some things here with the config - perhaps
    $myclass = new \My\Class();

    return $myclass;
};

and then you can access the service like so:

// from controller
$comp = $this->mycomponent;

// anywhere else
$di = \Phalcon\DI\FactoryDefault();

$comp = $di['mycomponent'];

Should probably be:

$di = new \Phalcon\DI\FactoryDefault();

or

$di = \Phalcon\DI\FactoryDefault::getDefault();

No, Nikolaos, you didn't understand. I mean - in what moment this should be done? 'registerAutoloaders' and 'registerServices' is invoked only if request is directed on controller of ModuleB, when in ModuleA this functions doesn't invoked.

No, it's not the same. I need a module services across all modules, i want to share only service between them, not requests. Like it done in Symfony2 per Bundle (Dependency injection) - https://martinsikora.com/symfony2-and-dependency-injection (Not exactly like that - per config or anything else, i mean that all modules have some function that will be called always per request, even if that request isn't intended to this module)

so Nikolaos aswer your question. from your reference atricle

Basically that's all. Now we can use MyService in any controller:

if you register any class in DI, then you can access it in every controller in your application. bootstrap file

$di['elements'] = function() {
    return new Elements();
};

your Elements class can extends extends \Phalcon\Mvc\User[Plugin|Module|Component] to access DI, or not and then using your Class as container of useful functions

using in controllers

$this->elements->function_in_elements_class();

Is not the same?

Oh, damn =). Look at example:

ModuleA:
 IndexController.php (indexAction)
 Module.php has 'registerAutoloaders' and 'registerServices'

and

ModuleB:
 IndexController.php (indexAction)
 Module.php has 'registerAutoloaders' and 'registerServices'

In both modules we have echo (with message 'initServieModuleA(B)) in 'registerServices' method and echo in controllers with message 'This is moduleA(B)'. Let's go in browser at url https://somesite.com/moduleA/index/index - we will see 'initServieModuleAThis is moduleA' ... and no messages about module B... if we go at https://somesite.com/moduleB/index/index - we will see 'initServieModuleBThis is moduleB'.... So .. as u can see - other module hasn't been initialized per request... and u saying to me add into di service from controller. So if i try to go to https://somesite.com/moduleA/index/index and to use some service from moduleB - if will have no chance to that, coz it will be not injected into di.

ok Ivan, i understand it now. I would like to know answer to your question too. For now i have no idea how to do this.

As was discussed with andresgut: there is no way to do that.

The question is clear. Although from another one's perspective it may no be clear enough. I suppose Symphony2 does the same as Zend Framework 2. I've noticed that phalcon works different. In ZF2 you would have a configuration file or you would return configurations in a initialisation method in Module.php.
All the configurations are processed ( en cached ) before any controller is dispatched. It is a pretty nice concept actually because you can keep all configurations within the module and just call the object providing a uniform interface with in turn allowes decoupling of components in an elegant way.

@ivan Im not sure about Symphony2 but in zf2 there is a /config/autoload folder which is used to store configuration files of (third party) modules thus allowing developers to manage configurations in 1 place and you could leave the module itself completely untouched. I've chosen the same approach to solve the problem we're having here.
Simply create a folder autoload within the main config folder. Then put this snippet in index.php:

$dir = DIR . '/../config/autoload'; $autoload = glob($dir . '/*.config.php'); foreach ($autoload as $file) { include_once($file); }

All files that end with *.config.php are now included. Something you may do in the config file is:
$di['myservice'] = 'SomeNamespace\SomeClass'; You can now access the service anywhere throughout your application.

If there is a better solution. I would like to hear it. I've chosen this method because I'm familiar with the concept.

Ohw I forgot to mention. It is a good idea to name each config file by the name of the module. Or use a prefix. I normally use: modulename.configtitle.config.php . Do not combine configurations from different modules. If you want to use your module in another project just do not forget to look in the autoload folder.