Setting up Coldspring within fusebox via the CS lexicons
After a couple of hours chatting back and forth on the fusebox mailing list I've got the coldSpring lexicons working. The reason this took so long was because I had a concern that to use any of the lexicons you have to use the initialize lexicon to setup coldspring (CS). This meant that I had to change my code that I'd already setup, somehow that didn't feel right. That said it's just a 5 min change (once you know what you're doing).
Cutting to the chase:
To get CS setup you need to initilise the CS factory, you do this using the initialize verb mentioned above. The best place to do this is in the appinit section of fusebox.xml.cfm as this is called as you start your app (it's like the onApplicationStart function in application.cfm). Within this function I call a fuseaction in my model circuit:
<fuseaction action="m.coldSpringSetup" />
</appinit>
Then inside my model circuit i have this fuseaction
<circuit access="public" xmlns:cs="coldspring/">
<fuseaction name="coldSpringSetup">
<cs:initialize coldspringfactory="servicefactory" defaultproperties="#application.defaultProperties#">
<cs:bean beanDefinitionFile="#expandPath('/config/coldspring.xml.cfm')#" />
</cs:initialize>
</fuseaction>
...
So what is it that we're doing here.
<circuit access="public" xmlns:cs="coldspring/"> -
we're declaring the namespace for the coldspring lexicons
cs:initialize - this calls the initialize verb from the coldspring lexicon folder.
coldspringfactory="servicefactory" - this is giving the
coldspring factory it's name.
cs:bean - this calls the bean verb from the coldspring lexicon folder.
beanDefinitionFile="#expandPath('/config/coldspring.xml.cfm')#" - this
passes my config file to coldspring
Once you've done this you'll all set up...wait, what! Yup, it's that easy.
Next you'll want to call some a method within CS, right?
returnvariable="variables.categoryService"
coldspringfactory="servicefactory" />
So what's going on here:
cs:get - this invokes the get verb from the coldspring lexicon
folder.
bean="categoryService" - this tells CS which bean (function or method)
in needs to get from the CS factory
coldspringfactory="servicefactory" - this tells CS which coldspring
factory to use.
And that all folks!
You can then call your objects as normal





<cs:get bean="ReactorFactory"
returnvariable="application.reactor"
coldspringfactory="servicefactory" />
One question:
within the <cs:get .../> tag you set: coldspringfactory="servicefactory"
I presume this must tie up with the application.servicefactory object that was created within the <cs:initialise .../> tag
How come its referenced as servicefactory and not as application.servicefactory?
The initlize verb prepends the coldspringfactory with: myFusebox.getApplication().getApplicationData().#fb_.coldspringfactory#
#fb_.coldspringfactory# being the name you give it.
The get verb also uses this to get the CS factory name:
#fb_.returnvariable#myFusebox.getApplication().getApplicationData().#fb_.coldspringfactory#.getBean
You only need that attribute if you want to use a different variable name - or have multiple factories (so you'd have multiple cs:initialize tags with different coldspringfactory attributes).
If anyone can help me with this i'd be much appreciated, I'm getting the following error:
Element SERVICEFACTORY is undefined in a CFML structure referenced as part of an expression.
For the life of me I can find a solution anywhere. If you have come across this before and found a solution, I'd love to hear it.
Cheers,
Tim
Initialised like zis:
<fuseaction name="coldspring">
<cs:initialize coldspringfactory="servicefactory">
<cs:bean beanDefinitionFile="#expandPath('/config/coldspring.xml.cfm')#" />
</cs:initialize>
</fuseaction>
Any Ideas?
Without seeing the context, this may not be relevant, but:
Are you only initialising ColdSpring (and the fusebox CS initialisation) on application initialisation, rather than on every request?
Have you ensured that access to this coldspring fuseaction is single threaded - your reported issue sounds like it could be a concurrency issue - if you had 2 concurrent requests to the initialisation action, the ServiceFactory could have been created by request 1, and be being accessed either as part of initialisation process - or from elsewhere in the application - and then request 2 will come along and begin initialising again - and in so doing destroy the ServiceFactory... which then doesn't exist for request 1...
Could that be your issue?
<globalfuseactions>
<appinit>
<fuseaction action="security-m.frameworkSetup" />
</appinit>
....
I hope that helps