A couple of thoughts keep popping back into my head. I have touched on a couple of these subjects before, but all these little stray thoughts are finally starting to crystallize.
First, why is the initialization feature exclusive to CApplicationComponent, and not generally available for any CComponent?
Lots of components actually need initialization after they’ve been constructed and configured - this feature is not just useful for application components. I find my self needing it again and again, and having to manually implement the IApplicationComponent interface.
The main difference between a CApplicationComponent and a CComponent, of course, is the fact that a CApplicationComponent is a pre-configured, lazy-loading object, which is a (virtual) member of CApplication.
In contrast, a CComponent is usually created and configured as needed, typically using Yii::createComponent() - which does not support initialization, and so, if your component does need initialization, you have to implement and call an initialization method yourself.
Of course, you could argue that the initialization feature wouldn’t be useful for CComponent, because there is no preset configuration that you can apply to it - and hence, nothing to initialize.
Which brings me to my next issue - why isn’t there a general mechanism that allows you to pre-configure components?
As it turns out, there is - but only for another specific type of component, namely CWidget - when used with a CWidgetFactory, you get the "skin" feature, which is essentially just a simple way to preconfigure components.
Why is that feature exclusive to widgets, and not generally available for components?
Here’s what I would recommend:
-
Drop the “skin” feature - it’s a terribly misleading misnomer in the first place.
-
Refactory CWidgetFactory into a more general-purpose component, e.g. CComponentFactory - adding support for preset configurations for any component, not just widgets.
-
Add a second (optional) argument to Yii::createComponent() that specifies which configuration to apply - let it default to "default", so that in your configuration file, you can specify a standard configuration for any component, and additional alternate configurations as needed.
-
Make the inititialization feature generally available in Yii::createComponent(), rather than specifically just for CApplicationComponent.
For backwards compatibility, CWidgetFactory could probably extend CComponentFactory, so that existing applications that don’t require CComponentFactory would need minimal changes.
My philosophy when it comes to frameworks, is that every framework feature should be as available as possible - and it seems that a couple of these features have been placed too deeply in the class hierarchy. Configuration and initialization are general-purpose features, not just useful to application components or widgets, but everywhere.
Widgets are still distinct from generic components: they solve UI-specific tasks, such as rendering views and auto-generating IDs - they belong to a controller, and they (optionally) execute in two stages, in a view-context. But the ability to pre-configure these components isn’t related to solving UI-specific task, and is not an exclusive requirement for this type of component.
Application components are still distinct from generic components: they are members of the application object, and they can lazy-load. But the ability to initialize after configuration isn’t an exclusive requirement for this type of component.
That’s why I think these features need to be untangled from application components and widgets, and made more generally available.