I am the owner and owner of the Alloy HMVC Framework , and I decided to have a core kernel, as you describe for several main reasons:
Useful as Factory
Having a central core object that you use to receive and load other objects eliminates the need for other people to know the dependencies of other objects that they can use in their structure. For example, a typical user simply knows that they want to use the router, but they do not want to create it themselves each time they want to use it.
Users prefer to write:
$router = $kernel->router();
Something like:
$router = new SomeFramework\Http\Router(new SomeFramework\Http\Request());
Or:
$router = SomeFramework\Http\Router::getInstance();
Instance management
The central core object can also ensure that objects will not be created multiple times when this is not required. Typically for objects such as Request, Response, Router, Session, etc., usually there is no need to have multiple instances.
So, the call to get the request instance looks like this:
$request = $kernel->request();
Will automatically create and create an instance of a new Request object on the first call, and then use a simple cache class to store the instance for use on subsequent calls to reduce overhead.
Simplifies dependency handling
A central core or kernel object can also be useful to simplify the processing of dependencies in the structure itself (using services as a locator). Instead of getting to know interdependent objects in front, you simply pass the main object and know that everything you need can be obtained directly from it. This is especially useful as part of the framework because you never know what users will want to do in their controllers. You simply provide them with a central core object, and they can extract everything they need from it. It is worth saying that this Locator Locator style approach has a well-known caveat about creating dependencies on the service locator itself with all the objects that use it. The downside is the trade-off with which you may or may not want to live, but it greatly simplifies the user-level code, so I chose it.
Provides a central extension point
One of the nice things about the central object being and being transmitted everywhere (and available on any controller) is that it provides a natural common extension point. The fusion allows users to add their own methods to the Kernel object, which are proxied through the __call magic function:
$kernel->addMethod('bark', function() { echo 'Woof!'; });
That allows you to use it anywhere in the application where the kernel is available:
$kernel->bark();
This provides a good way for things like plugins to provide custom functions or create their own factory methods in the kernel to create helper objects, etc., without creating a new plugin architecture for it.
Regarding class configuration
Regarding your question about why you would not want to do this:
$myclass->get_configs(); // get my configs $myclass->do_stuff($this->my_configs); // use them
Instead of this:
$myclass_configs = $this->config->get('configs_for_myclass');
This is due to two main reasons:
(1) Repeated functionality in all classes for "get_config". To save DRY code, you still have to make all your classes from a common base class, which is likely to be an inheritance and deepen the class hierarchy.
(2) When you make multiple method calls on an object, it would be tiring and ugly to go through configurations every time, that is:
$myclass->do_stuff($this->my_configs); $myclass->do_other_stuff($this->my_configs); $myclass->do_more_stuff($this->my_configs);
It is much easier to instantiate an object with a configuration once:
$myclass = new MyClass($myclass_configs); $myclass->do_stuff(); $myclass->do_other_stuff(); $myclass->do_more_stuff();
And since this configuration has to come from somewhere, and you donβt necessarily want your users to type it all or harshly point to it somewhere else, you just need to pull it out of the common main object because it already loaded A common configuration file that is used throughout the application.