zendframework/zend-modulemanager

RFC: ModuleManager v3 changes proposal

Xerkus opened this issue · 2 comments

I intend to make a prototype for v3 that looks more like a ConfigAggregator hybrid with module manager benefits. I think it will improve the way module manager works with zend-mvc applications that also have console applications, and will make module manager more easily reusable in different contexts.

  • Change module to be either a class name or an object, drop namespace + Module resolution
  • Make modulemanager accept config providers as regular modules. That is, if no getConfig() is defined and is callable, then invoke to collect config.
  • Move glob config paths into a regular config provider as can be seen in Expressive skeleton
  • Rearrange events and listeners if necessary to let modules extend module manager behavior. For example, modules that are enabling most of Zend\ModuleManager\Feature\*ProviderInterface.
    Likely load modules event will need to be split into init modules and load modules. Or most of load module listeners moved to load modules post
  • Rework module manager to let modules be loaded outside of zend-mvc application.
    • Application independent config aggregating $config = $moduleManager->getMergedConfig() roughly doing following:
      • Instantiate modules and config providers, if needed
      • If module is of ModuleManagerEventListenersProviderInterface, attach provided listeners
      • Recover cached config or collect and merge config from providers and modules
      • Dump merged config into cache
      • Trigger post-config-merge event to allow previously registered listeners to provide extra non-cacheable config. Service config providers go here
      • Final merged config is returned and could then be used to configure container
    • Mvc specific part provided by Zend\Mvc\Module:
      • Provides dependencies config for all the mvc services
      • Registers mvc specific service config provider listeners.
      • Registers listener to collect modules with OnBootstrapListener feature and store them as mvc bootstrap listeners in extra uncacheable config
      • Provides Application factory that will pick up bootstrap listeners from config and attach to MvcEvent::EVENT_BOOTSTRAP event

Expected usage is much like with Expressive:

use Zend\ConfigAggregator\ArrayProvider;
use Zend\ConfigAggregator\PhpFileProvider;
use Zend\ModuleManager\ModuleManager;

$cacheConfig = [
    'config_cache_path' => 'data/config-cache.php',
];
$moduleManager = new ModuleManager([
    // Include cache configuration
    new ArrayProvider($cacheConfig),
    // Framework stuff
    \Zend\Mvc\Module::class,
    \Zend\Router\Module::class,
   
    // Mvc module that is only providing config can be a regular config provider
    Application\ConfigProvider::class,

    new PhpFileProvider('config/autoload/{{,*.}global,{,*.}local}.php'),
    new PhpFileProvider('config/development.config.php'),
], $cacheConfig['config_cache_path']);
return $moduleManager->loadModules()->getMergedConfig();

$container = require 'config/container.php';
$app = $container->get(\Zend\Mvc\Application::class);
$app->bootstrap()->run();

I might need to remove the concept of module name to allow config providers, module instances in a way that would not be annoying or error-prone.
It would be rather bad:

$moduleManager = new ModuleManager([
    // Include cache configuration
    'cache_config' => new ArrayProvider($cacheConfig),
    // Framework stuff
    \Zend\Mvc\Module::class,
    \Zend\Router\Module::class,
   
    // Mvc module that is only providing config can be a regular config provider
    'Application' => Application\ConfigProvider::class,

    'glob_config' => new PhpFileProvider('config/autoload/{{,*.}global,{,*.}local}.php'),
    'dev_config' => new PhpFileProvider('config/development.config.php'),
], $cacheConfig['config_cache_path']);

Eg, if I forgot to specify keys for PhpFileProvider instances, what would be the module name? Module manager tracks stuff that is already loaded by module name. Result might be... interesting.

This repository has been closed and moved to laminas/laminas-modulemanager; a new issue has been opened at laminas/laminas-modulemanager#3.