1

I am trying to use my service layer in my own front-controller style framework and I've always been taught to decouple the service layer from the controller layer.

This is causing me issues as I need to access important front-controller methods from my services, so I'm jumping through hoops to try and make this happen.

I noticed when looking at Coldbox however that the actual framework regularly passes the Coldbox controller through to its services.

Can and should this really be done?

The problem I have specifically that my controller/handler calls a service which gets a load of widgets for a page request, it then loops over each one and renders each widget, but each widget is itself a controller/handler and the controller/handler needs the front-controller.

How can this be done without passing in the front-controller or is my architecture all wrong?

CURRENT SERVICE CODE (shortened)

<cffunction name="renderWidgets" access="public" output="false" returntype="string" hint="I return an the prequested webpage URL.">
<cfargument name="source" type="string" default="" />
<cfargument name="templateId" type="string" default="" />
<cfargument name="webPageId" type="string" default="" />
<!--- set original template HTML --->
<cfset stuReturn.renderedHTML = arguments.source />
<!--- get assigned widgets and properties --->
<cfset stuReturn.qryTemplateObjects = findTemplateObjectAssignments({templateId=arguments.templateID}) />
<!--- if found --->
<cfif stuReturn.qryTemplateObjects.recordcount>
    <!--- loop over assigned widgets --->
    <cfloop query="stuReturn.qryTemplateObjects">
        <!--- create struct  --->
        <cfset stuReturn.stuTemplateObjectAssignment = queryrowtostruct(stuReturn.qryTemplateObjects, stuReturn.qryTemplateObjects.currentrow) />
        <!--- get the widget object --->
        <cfset stuReturn.renderedHTML = stuReturn.renderedHTML & getFrontController().getWidget(stuReturn.stuTemplateObjectAssignment.objectId).render() /><!--- this is the problem, no access to getFrontController() --->
    </cfloop>
</cfif>
<!--- return rendered HTML --->
<cfreturn stuReturn.renderedHTML />

  • If you find you need controller methods in your services, I would suggest that maybe the architecture needs to be tweaked a bit. Can you give a code example of what you are referring to? Maybe there is an easier/better way to handle it. – Scott Stroz Nov 03 '11 at 12:35
  • I have a system which displays one or more intelligent widgets on a webpage. Each widget extends a controller, it requires: 1] handlers e.g. method1, method2 2] model access via services to get data 3] a view to display the widget's output (kind of viewlet). To render the page the system needs: 1] to get the request's template HTML source 2] get a list of all widget objects from the database assigned the page 3] loop over each assigned widget >>3.1] get the widget object >>3.2] run the widget method requested (e.g.method1) which >>>3.2.1] gets data >>>3.2.2] sets view and returns html – Puc Covelli Nov 03 '11 at 12:58
  • Basically I really need to loop in my controller over each widget and render them. Usually I would do all looping inside a service call, but I can't really do this in this case. Is it ok to put looping logic, if's etc inside a controller method (i usually have them very clean, calling only simple service calls)? – Puc Covelli Nov 03 '11 at 13:02
  • 1
    I have to ask...why do your widgets 'extend a controller', that sounds like something that should be handled by your service/model? Your service layer (and the rest of your application's model) should not have any reference to the framework being used (if any). – Scott Stroz Nov 03 '11 at 16:19
  • Widgets are basically controllers, as they have many methods and each method needs model and view. Does that make sense? – Puc Covelli Nov 03 '11 at 17:17
  • Actually...no, it doesn't. If you need to pass your controller into your services, you are doing something wrong. Your services and other model code should be able to stand by itself, it should not know anything about your controller or framework. If architected properly, your model should be able to be dropped into any application or framework without having to make any changes. – Scott Stroz Nov 04 '11 at 03:09
  • I know that this is a long time past, but if you need controllers in your view in ColdBox, then you should probably look at viewlets. Viewlets are a renderview call to an event that returns output instead of rendering itself. I really would recommend against putting any view elements at all in your service. There's bound to be a way to generate these widgets without doing it in the service. – Stephen Moretti Feb 03 '12 at 00:53

0 Answers0