Coldbox 3.1 - Module onLoad() and Service dependencies with wirebox

Hi,

I don’t know if this a bug or expected behaviour or what… But it looks like the module life cycle in ColdBox 3.1 isn’t quite as documented.

ColdBox Version : 3.1

Background:
I want each module in an application to register some data at the point at which it loads, so that another module can tap into this data at a later date.
This data is relatively static, but not static enough just to write it out somewhere and forget about it. Its can be changed in the life time of the application, but don’t want to have to reload the entire application when one small element is changed. It would be too arduous for the client module to go and request the information from each module when it needs it. The data can’t be stored in a database, because some processing is required to build the data and so on.

Anyway, having gone through all the options this is the way that we wanted to go:

Problem we’ve got:

  • Every service has at least one WireBox dependancy, onLoad throws an error sorting out the dependencies through the stack of inter-related services.
    Solutions we tried:

  • Calling the service from postModuleLoad http://wiki.coldbox.org/wiki/Modules.cfm#Interception_Points - this resulted in the same problem as using onLoad

  • A bunch of random stuff that has no bearing in hindsight really.

What actually worked :

  • I noticed a mention that the ModuleConfig.cfc is actually treated as an interceptor, so I semi randomly picked “afterConfigurationLoad” and called the service method from this function in the ModuleConfig.cfc. This actually loaded the service instance, called the method and registered some test data.
    So from this I’m concluding that even though the module is “Active” at the end of onLoad() and postModuleLoad(). The wirebox dependencies haven’t actually been loaded. This diagram would suggest otherwise : http://wiki.coldbox.org/wiki/Modules.cfm#Module_Activation given that one of the middle items is “Module wirebox DSL loaded”.
    However practice suggests that it is not until after the configuration call is completed that wirebox dependencies have been satisfied.

The bit of code that I was using to test this with was :

function afterConfigurationLoad () {

writedump(var=this,label=“this”);

try {

var adminService = controller.getWireBox().getInstance(‘AdminService@admin’);

adminService.activate();

}

catch (any e) {

writedump(var=e,label=“catch”) ;

}

writedump(var=application,label=“application”)

writedump(var=variables,label=“variables”,abort=“true”);

}

In the end, I was simply changing the function name to try different interception points.
The dumps were simply to help me see what error was thrown before any error trapping kicks in, what was available in the current ModuleConfig.cfc, whether some application variables had been registered by the “activate” function in the adminService and what was in the variables scope. The admin service is defined using binder.map(“AdminService@admin”).to("#moduleMapping#.model.adminService"); in the configure function in the same ModuleConfig.cfc

Happy to be proven wrong or told I’m doing something stupid, but this does seem to be about right.

Regards

Stephen

Answers below:

Hi,

I don’t know if this a bug or expected behaviour or what… But it looks like the module life cycle in ColdBox 3.1 isn’t quite as documented.

ColdBox Version : 3.1

Background:
I want each module in an application to register some data at the point at which it loads, so that another module can tap into this data at a later date.
This data is relatively static, but not static enough just to write it out somewhere and forget about it. Its can be changed in the life time of the application, but don’t want to have to reload the entire application when one small element is changed. It would be too arduous for the client module to go and request the information from each module when it needs it. The data can’t be stored in a database, because some processing is required to build the data and so on.

Anyway, having gone through all the options this is the way that we wanted to go:

Was this in the documentation? If so, the docs are wrong, controller.getModel() does not exist. The latter is correct.

Problem we’ve got:

  • Every service has at least one WireBox dependancy, onLoad throws an error sorting out the dependencies through the stack of inter-related services.

This has been an issue and resolved in ColdBox 3.5 in the development branch. You are absolutely right, if you used some plugins or interceptors for dependencies, the chicken and the egg issue would arise. Very pesky to discover and incredibly hard to solve, but now we have a working solution in our development branch and ready for Release Candidate in 2 weeks.

Answers below:

Ditto.

Hi,

I don’t know if this a bug or expected behaviour or what… But it looks like the module life cycle in ColdBox 3.1 isn’t quite as documented.

ColdBox Version : 3.1

Background:
I want each module in an application to register some data at the point at which it loads, so that another module can tap into this data at a later date.
This data is relatively static, but not static enough just to write it out somewhere and forget about it. Its can be changed in the life time of the application, but don’t want to have to reload the entire application when one small element is changed. It would be too arduous for the client module to go and request the information from each module when it needs it. The data can’t be stored in a database, because some processing is required to build the data and so on.

Anyway, having gone through all the options this is the way that we wanted to go:
Each module has a method in one of its services that builds the data and registers it.
onLoad in ModuleConfig.cfc calls this service method when the module loads (http://wiki.coldbox.org/wiki/Modules.cfm#Interceptor_Methods:_onLoad().2C_onUnLoad().2C_etc)
Problem we had :
controller.getModel() doesn’t work - you have to use controller.getWireBox().getInstance(“SERVICENAME”) (the above onLoad documentation could do with a tweak)

Was this in the documentation? If so, the docs are wrong, controller.getModel() does not exist. The latter is correct.

Yes it is. It’s under the onload/onUnload documentation link shown above.

Problem we’ve got:
Every service has at least one WireBox dependancy, onLoad throws an error sorting out the dependencies through the stack of inter-related services.

This has been an issue and resolved in ColdBox 3.5 in the development branch. You are absolutely right, if you used some plugins or interceptors for dependencies, the chicken and the egg issue would arise. Very pesky to discover and incredibly hard to solve, but now we have a working solution in our development branch and ready for Release Candidate in 2 weeks.

Marvellous! I’m glad I’m not going loopy.

Hopefully, documenting this here will help anyone else on 3.1 avoid this unfortunate pit fall.

Thanks Luis. I look forward to the release of 3.5

Stephen