Decorating the same object from multiple addons


#1

I’m trying to create a project that has a core, and multiple plugins. All of these are addons that are used by a virtually empty app that serves to contain installation specific customisations.

An example to clarify: The core contains a computed property in its application controller that represents the contents of the sidebar as an array. The client app doesn’t have an application controller of its own, but because it depends on the core addon, the application controller automagically appears in the correct spot, and the sidebar is rendered correctly.

Enter plugin 1, an addon that, for the sake of this example, simply needs to add an additional element to that sidebar array. Plugin 1 also depends on the core, so in its application controller it can import the core’s application controller (import ApplicationController from 'core/controllers/application') and extend it, modifying the sidebar array’s computed property by calling this._super(), adding the element and returning the result.

Now, if I add plugin 1 underneath the core in the client app’s package.json, plugin 1’s application controller will be used in the client app, and render the sidebar with plugin 1’s additional element in place. So far so good.

The problem starts when I have plugin 2, that also needs to add an element to that same sidebar array. I could make it depend on plugin 1, and import its application controller in plugin 2’s and do the same thing again I described above, and that would work. But that assumes that plugin 1 and 2 will always be used together, and that is not the intention.

Is there a way I can modify the core’s application controller (or any other part of the app for that matter) from any number of plugin-adddons, without each plugin having to depend on anything other than the core?


#2

Hmm… how about reopen the class…? That will work I think …


#3

I considered that, you could have every plugin reopen the application controller instead of extending it But then the question becomes, where do I put those reopen statements, so the client app will take them in to account for all plugins?

If I simply put it in plugin/addon/controller/application.js for every plugin, I have the same problem as with extend: only the change made by the plugin that is specified lowest in the client app’s package.json is used.