Skip to content
This repository has been archived by the owner on Jan 8, 2020. It is now read-only.

Allow modules to load their own dependencies #5651

Closed
wants to merge 3 commits into from

Conversation

radnan
Copy link
Contributor

@radnan radnan commented Dec 30, 2013

Just testing the waters here.

Let's say our application has 3 modules A, B, and C. Module B depends on modules C, D, and E.

A
B -> C, D, E
C

But in our application.config.php we only specify A, B, and C.

return array(
    'modules' => array(
        'A',
        'B',
        'C',
    ),
);

This little patch will allow B to load its dependencies D and E without having the user to specify it in their application.config.php.

namespace B;

use Zend\ModuleManager\ModuleManager;

class Module
{
    public function init(ModuleManager $modules)
    {
        $modules->loadModule('C');
        $modules->loadModule('D');
        $modules->loadModule('E');
    }
}

test whether a module can load a module that was not in the initial list
of modules to be loaded
@@ -34,11 +34,6 @@ class ModuleManager implements ModuleManagerInterface
protected $event;

/**
* @var bool
*/
protected $loadFinished;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BC break

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, reverted.

remove unnecessary loadFinished boolean
previously the loadFinished prop was only used in binary form
(true/false). change to integer (0..) so as to keep track of nested
loadModule() calls.
radnan added a commit to radnan/rdn-doctrine that referenced this pull request Jan 26, 2014
@EvanDotPro EvanDotPro added this to the 2.3.0 milestone Mar 1, 2014
@EvanDotPro EvanDotPro self-assigned this Mar 1, 2014
@EvanDotPro
Copy link
Member

Thanks!

I really can't think of any reason not to merge this. It's something I semi-planned on supporting in the ModuleManager anyway, but never polished (ModuleEvent object reference being the primary issue). I'm going to sleep on it just to make sure it won't break anything else I haven't thought of.

@Ocramius
Copy link
Member

Ocramius commented Mar 2, 2014

@radnan would multiple calls to loadModule with the same module name be ignored? See #3443 for previous discussions on this automatic loading system.

@radnan
Copy link
Contributor Author

radnan commented Mar 2, 2014

Yes, that should be fine. The loadModule() method loads the module object and saves it inside the $loadedModules property before triggering the module load event which triggers init() and all other module goodies. So, a later call with the same module name will bail out when it notices a module object already exists inside $loadedModules.

As a bonus this also handles circular dependencies very nicely.

Only caveat is you cannot use loadModule() and getModuleDependencies() together. The dep checker checks required modules as soon as the parent module is loaded and doesn’t wait until all other modules are loaded.

@EvanDotPro
Copy link
Member

Yeah, I don't even know how the module dependency thing slipped in there. We had something like this in an early beta, but I explicitly removed it because it made no sense at all during runtime.

I don't see an incompatibility with getModuleDependencies() as a blocker for this.

@Xerkus
Copy link
Member

Xerkus commented Mar 3, 2014

My concern with this approach is that it will, if used, override module loading order, which can be very important during configuration merging.

@Ocramius
Copy link
Member

Ocramius commented Mar 3, 2014

@Xerkus whoever wants to use a module that makes use of this feature and does NOT want the automatic initialization of dependency modules can just subclass and re-define the init() method, I suppose.

@stefanotorresi
Copy link
Contributor

👍
it's a very nice feature, but it makes DependencyIndicatorInterface effectively redundant, if not totally irrelevant.
it would have been ideal if the two features could have been merged in one single listener. after all the dependency list was pretty much useless without the module loading, as @EvanDotPro said.
maybe we could just add a @todo to remember some cleaning for zf3? :)

@weierophinney
Copy link
Member

My only question at this time is: can we have some more robust tests to ensure that we don't get into an infinite loop situation, please?

weierophinney added a commit that referenced this pull request Mar 10, 2014
Allow modules to load their own dependencies
weierophinney added a commit that referenced this pull request Mar 10, 2014
- Moved new test assertions into their own test case to ensure they failed
  before the patch was made.
weierophinney added a commit that referenced this pull request Mar 10, 2014
@weierophinney
Copy link
Member

After discussion in IRC with @EvanDotPro, merged to develop for release in 2.3.0. Separated new assertions into their own test case to validate that the behavior did not work prior to the change.

@Thinkscape
Copy link
Member

Only caveat is you cannot use loadModule() and getModuleDependencies() together. The dep checker checks required modules as soon as the parent module is loaded and doesn’t wait until all other modules are loaded.

Note: Because deps loading will now live inside module's php code (as opposed to config file) it will be harder to automate deployment/installation. There is no simple way to "retrieve module's dependencies" and the only effect of a misconfiguration or missing modules is an error being thrown. That's bad for stuff like ZFTool or any form of module installation automation.

@radnan radnan deleted the feature/sub-module branch March 11, 2014 16:44
radnan added a commit to radnan/zf2 that referenced this pull request Mar 11, 2014
@radnan
Copy link
Contributor Author

radnan commented Mar 11, 2014

@Thinkscape could you give me an example for your situation? I haven't used the dependency checker ever and I'm not exactly sure of the specifics of the use-case.

I could submit a patch to ModuleDependencyCheckerListener so that it uses the loadModules.post event instead and plays nice with this way of loading modules.

@turrsis
Copy link
Contributor

turrsis commented May 7, 2014

When i load A, B configs order is A, B.
But if i load A -> B configs order is B, A.
This is bug or this is ok?

@danizord
Copy link
Contributor

danizord commented May 7, 2014

@turrsis This is ok. A requires B, so the ModuleManager will load B first, then A.

@thestanislav
Copy link
Contributor

What if two modules try to load each other?

@Ocramius
Copy link
Member

@thestanislav you'd get a maximung nesting level error AFAIK. You can write a test for it.

@radnan
Copy link
Contributor Author

radnan commented May 12, 2014

@thestanislav That's what #5948 tests for. It won't result in an error.

weierophinney added a commit to zendframework/zend-modulemanager that referenced this pull request May 15, 2015
…re/sub-module

Allow modules to load their own dependencies
weierophinney added a commit to zendframework/zend-modulemanager that referenced this pull request May 15, 2015
- Moved new test assertions into their own test case to ensure they failed
  before the patch was made.
weierophinney added a commit to zendframework/zend-modulemanager that referenced this pull request May 15, 2015
gianarb pushed a commit to zendframework/zend-modulemanager that referenced this pull request May 15, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants