Hi everyone, I'm stuck on a problem for some days ...
# fw1
b
Hi everyone, I'm stuck on a problem for some days now. I'm trying to implement a service for assets, let's call it
assetService.cfc
. It would contain
getStyles()
,
getMetaData()
,
getScripts()
and all sort of things. Now, depending on the area of the application I'm in, these functions should ouput different things, so I created multiple services (
frontendAssetService.cfc, backendAssetService.cfc, ect.
) that all implement the same interface
IAssetService.cfc
, making those functions required. Whenever there will be a new area in the app, I just have to create a new "sub-service". Now in my assetService.cfc:init() I was returning an instance of one of those other sub-services, which worked well until I turned off
reloadApplicationOnEveryRequest
and realized the service was cached as a singleton and would always return the sub-service that was created on the last app-reload. "No problem", I thought and switched the assetService.cfc to transient, however I cannot seem to invoke them directly with
getAssetService()
in my controller.cfc. I would have to get it via
fw.getBeanFactory().getBean('assetService')
. "Back to singleton", I said and implemented the
onMissingMethod()
method, which then invoked the correct sub-service, checks for the function to exist there and returns it. It seems like a big hack. Does anyone know a better solution for this? I feel like I'm running into the same wall again and again. Eventuall I would just like to invoke
rc.htmlHeadStyles=getAssetService().getStyles()
in my controller.cfc instead of having a very big
<cfif><cfelse>
in my layout.cfm. Any ideas highly welcome! Cheers, Boris
Oh no... It's probably just easiest to invoke
getFrontendAssetService()
in the corresponding subsystems and
getBackendAssetService()
in the others(?) 🤦‍♂️
d
I think you've discovered the best solution. On the surface, it may seem like having a "smart" component like you were trying create makes things easier, it often makes for more confusing code. Because you see something like getAssetService().getStyles() and think you know what it's doing from looking at the code, it can be producing things you don't want. You could have a
getStylesByService(required string name)
method, that could load the styles for various services, that way you could do:
Copy code
rc.serviceName = 'frontend'; // this could come from session scope

rc.htmlHeadStyles=getAssetService().getStylesByService(rc.serviceName);
Or you could just set an
rc.AssetService
variable at the controller which passes in the correct version of the component.
b
Thanks for the reply, Dan! I think it's easiest to use the specific services directly, in that way it's clear to everybody maintaining the code. I was always wondering wether adding a whole service instance to the rc was a good idea or not. My colleague sometimes even adds the controller itself to the rc, which I am not a big fan of, but I could't come up with a proper reason other than "it complicates the inuitive flow of FW/1". Cheers, Boris