Services and models oh my

303 views
Skip to first unread message

Dave Merrill

unread,
Aug 29, 2010, 3:49:09 PM8/29/10
to framework-one
(New to fw1 this weekend, apologies etc...)

Do I understand that the typical fw1 structure for the components the
interact with the back end is this:

- Services handle list method queries themselves

- For detail forms, services run the query themselves, create an
instance of the corresponding transient model object, populate it from
the query, and put the model object in the request collection for the
view the use.

- For saves, services create an instance of the transient model
object, populate it from submitted data, and ask it if it's valid. If
not, they put the model instance and error collection into the request
collection, and set the view to the edit form. If it is valid, the
service does the save itself, using the populated model as the source
of the data, and the controller's afterSave method redirects back to
the list (or wherever).

- For deletes, services do the query themselves.

Question #1: Am I on the right track with this typical flow? Any other
common strategies people use?

Question #2: For saves, if the data isn't valid, how to you keep the
controller's afterSave model from doing the redirect it's supposed to
do if the save was successful? Have the model throw a validation
error, and handle the exception by redisplaying the form from the
model and error collection?

Thanks for any thoughts,
Dave

Sean Corfield

unread,
Aug 29, 2010, 6:49:04 PM8/29/10
to framew...@googlegroups.com
On Sun, Aug 29, 2010 at 12:49 PM, Dave Merrill <enig...@gmail.com> wrote:
> Do I understand that the typical fw1 structure for the components the
> interact with the back end is this:

Well, I'm not sure there's a "typical" structure but the underlying
MVC pattern tries to ensure that:
* there's no logic in views
* the model is completely independent of the controller / views
* the controller is the traffic cop that knows about application flow
and the HTTP request / response

With that in mind, let's look at your questions:

> - Services handle list method queries themselves

Yes, the query belongs in the model (services are part of the model -
they know nothing about FW/1 and they know nothing about forms /
URLs).

FW/1 allows you to omit a controller method if all it would do is
delegate directly to a service method like this:

function doSomething( rc ) {
rc.data = someService.doSomething( argumentCollection = rc );
}

For a simple list operation, that's often the case so you can rely on
a service method:

function list() {
var result = entityLoad( 'stuff' );
return result;
}

This would put an array of stuff objects in rc.data - without any
other infrastructure.

> - For detail forms, services run the query themselves, create an
> instance of the corresponding transient model object, populate it from
> the query, and put the model object in the request collection for the
> view the use.

Yup, you could just have a service like this:

function edit( numeric id = 0 ) {
if ( id ) {
return entityLoad( 'stuff', id, true );
} else {
return entityNew( 'stuff' );
}
}

That would set rc.data to either a populated object based on the id or
an empty object (if id not provided or was zero).

> - For saves, services create an instance of the transient model
> object, populate it from submitted data, and ask it if it's valid. If
> not, they put the model instance and error collection into the request
> collection, and set the view to the edit form. If it is valid, the
> service does the save itself, using the populated model as the source
> of the data, and the controller's afterSave method redirects back to
> the list (or wherever).

Here's where the controller comes in. It knows about data from the
form / URL so it would coordinate the validation of that data. There
are several ways to handle this, depending on where you put your
validation logic. One possibility is:

// controller
function saveStart( rc ) {
... validate the data in rc ...
if ( invalid ) {
rc.message = 'Your data is not valid';
redirect( 'stuff.edit', 'all' );
}
}

function saveEnd( rc ) {
// data has been saved, redirect to confirmation page or whatever
rc.message = 'Your data has been saved';
variables.fw.redirect( 'stuff.list', 'message' );
}

// service
function save( numeric id = 0, string firstName, string lastName, ...
other args ... ) {
var object = 0;
if ( id ) {
object = entityLoad( 'stuff', id, true );
} else {
object = entityNew( 'stuff' );
}
// populate the object
// save it
entitySave( object );
}

If you're calling your model / services directly from your
controllers, you have more flexibility and you might do something
like:

// controller
function save( rc ) {
param name="rc.id" default="0";
var object = variables.stuffService.get( rc.id );
variables.fw.populate( object );
rc.errors = object.validate();
if ( arrayLen( rc.errors ) ) {
// invalid, redisplay form with errors
setView( 'stuff.edit' );
} else {
// valid, save it and redirect
variables.stuffService.save( object );
rc.message = 'Your data was saved';
variables.fw.redirect( 'stuff.list', 'message' );
}
}

The downside of that is it populates your object first - so your
object must be able to handle invalid data - and, if you're using ORM
(in CF9/Railo), you need to ensure your object won't get automatically
saved.

Another possibility is this - using validation as a service:

// controller
function save( rc ) {
rc.errors = variables.stuffService.validate( argumentCollection = rc );
if ( arrayLen( rc.errors ) ) {
// invalid, redisplay form with errors
setView( 'stuff.edit' );
} else {
// valid, save it and redirect
param name="rc.id" default="0";
var object = variables.stuffService.get( rc.id );
variables.fw.populate( object );
variables.stuffService.save( object );
rc.message = 'Your data was saved';
variables.fw.redirect( 'stuff.list', 'message' );
}
}

Or - if your service save() takes individual attributes instead, like
the first example above:

// controller
function save( rc ) {
rc.errors = variables.stuffService.validate( argumentCollection = rc );
if ( arrayLen( rc.errors ) ) {
// invalid, redisplay form with errors
setView( 'stuff.edit' );
} else {
// valid, save it and redirect
variables.stuffService.save( argumentCollection = rc );
rc.message = 'Your data was saved';
variables.fw.redirect( 'stuff.list', 'message' );
}
}

> - For deletes, services do the query themselves.

Yes, probably after the controller has validated that you can delete
this object.

Hopefully that helps answer your questions?
--
Sean A Corfield -- (904) 302-SEAN
Railo Technologies, Inc. -- http://getrailo.com/
An Architect's View -- http://corfield.org/

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood

Dave Merrill

unread,
Aug 30, 2010, 10:11:16 AM8/30/10
to framework-one
Sean, thanks a ton for your thoughtful and detailed reply. Most
helpful overview of the options. Some questions interleaved; I
appreciate your time very much.


> > - Services handle list method queries themselves
>
> Yes, the query belongs in the model (services are part of the model -
> they know nothing about FW/1 and they know nothing about forms /
> URLs).

The distinction I'm after is between the roles of the service and
model. Seems it's that the service handles operations involving data
collections (list), which are effectively static methods of the domain
object. Models are smart value objects that contain data and business
rules for one object instance. It's the model that understands when
its instance data is valid to save, for instance. Do I have that
right?

Where that gets fuzzy to me is that if it's the model that understands
when an object instance can be deleted, for example. Is it the service
that understands about deleting a set of multiple objects? Don't want
this similar logic in both places, so it must be in the model, and the
collection vs. instance separation breaks down. (At least in this
discussion, I'm interested in representing collections as cf query
objects, not arrays of populated object instances, for performance and
simplicity.)

It's not that I'm looking for the One True Way, but it seems useful to
have a Way We Usually Do It, to know where to look for the code, and
so this thought process doesn't have to happen every time we write
something new.


> FW/1 allows you to omit a controller method if all it would do is
> delegate directly to a service method like this:
>
> function doSomething( rc ) {
> rc.data = someService.doSomething( argumentCollection = rc );
>
> }
>
> For a simple list operation, that's often the case so you can rely on
> a service method:
>
> function list() {
> var result = entityLoad( 'stuff' );
> return result;
> }
>
> This would put an array of stuff objects in rc.data - without any
> other infrastructure.

Isn't this what suppressImplicitService disables in 1.2, and that will
be gone completely in 2.0? With that feature shut off, how else would
would the service get called if the controller doesn't do it
explicitly? I thought the ability to skip writing a pass-through
controller method just to call the same method on a service was a nice
shortcut. What's the rationale behind deprecating it?


> > - For saves, services create an instance of the transient model
> > object, populate it from submitted data, and ask it if it's valid. If
> > not, they put the model instance and error collection into the request
> > collection, and set the view to the edit form. If it is valid, the
> > service does the save itself, using the populated model as the source
> > of the data, and the controller's afterSave method redirects back to
> > the list (or wherever).
[...]
> If you're calling your model / services directly from your
> controllers, you have more flexibility and you might do something
> like:
>
> // controller
> function save( rc ) {
> param name="rc.id" default="0";
> var object = variables.stuffService.get( rc.id );
> variables.fw.populate( object );
> rc.errors = object.validate();
> if ( arrayLen( rc.errors ) ) {
> // invalid, redisplay form with errors
> setView( 'stuff.edit' );
> } else {
> // valid, save it and redirect
> variables.stuffService.save( object );
> rc.message = 'Your data was saved';
> variables.fw.redirect( 'stuff.list', 'message' );
> }
> }

That's pretty much what this looked like in my head -- validation is
done by populating a model instance and either asking it if it's valid
and saving if so, or asking it to save, expecting that to fail if
there are validation errors. Couple questions:

- The controller doesn't instantiate the model instance directly; it
asks the service for the instance, but then populates it itself. It
makes sense to me that populating gets done by the controller, since
the service doesn't know about form/url/rc, but it's interesting to me
that it doesn't create the model instance. Is that pretty standard,
models isolated behind a service? Trying to understand where that
layer of abstraction is a benefit, and all that occurred to me was if
the actual model you got might be different under some circumstances
that the service would manage. Can you give me an example?

- Lower level question, but if you do a redirect with a message, that
ends up in rc, right? How do you access that from a layout, so there's
standard infrastructure to display it?


> The downside of that is it populates your object first - so your
> object must be able to handle invalid data - and, if you're using ORM
> (in CF9/Railo), you need to ensure your object won't get automatically
> saved.

No ORM, yet. If the structure of your model was that it threw
immediately on invalid field assignments, that'd seem to limit your
flexibility a lot; you'd have to try/catch each assignment
individually. Is that a common strategy?


> Hopefully that helps answer your questions?
>
> Sean A Corfield -- (904) 302-SEAN
> Railo Technologies, Inc. --http://getrailo.com/
> An Architect's View --http://corfield.org/
>
> "If you're not annoying somebody, you're not really alive."
> -- Margaret Atwood


Very very helpful discussion, thanks again Sean.

Dave

Sean Corfield

unread,
Aug 30, 2010, 12:27:45 PM8/30/10
to framew...@googlegroups.com
On Mon, Aug 30, 2010 at 7:11 AM, Dave Merrill <enig...@gmail.com> wrote:
> The distinction I'm after is between the roles of the service and
> model.

The services (in FW/1) are simply a gateway to your model. Really they
are *part* of your model.

> Models are smart value objects that contain data and business
> rules for one object instance.

That's very confusing terminology - probably why you're struggling here.

FW/1 is MVC:
* Model - all of your business logic and data
* View - HTML display pages
* Controller - control flow / traffic cop

In FW/1, that's
* Model: services and everything they touch
* View: views and layouts
* Controller: FW/1 itself and your controllers

It's model (singular) not models. I've seen that plural notation
somewhere recently and it's very jarring. Your application has one
model, made up of all your (smart) domain objects and the
orchestration code (usually 'services' of some sort). Orchestration
code is needed for operations that don't naturally live in a single
domain object.

If you haven't already, I'd recommend reading my "Beans and DAOs and
Gateways, Oh My!" chapter in the Adobe ColdFusion Anthology (from
Apress) or the original article in the FAQU: Do More Code Less issue.
It covers several different ways of organizing model code in layers.

> Isn't this what suppressImplicitService disables in 1.2, and that will
> be gone completely in 2.0?

You can enable it in 2.0 but it will be off by default (in 1.2 it's on
by default but you can disable it).

> With that feature shut off, how else would
> would the service get called if the controller doesn't do it
> explicitly?

That's the point. The controller would need a call to service() - or
would need to call the underlying service directly.

> What's the rationale behind deprecating it?

It's been discussed a few times on the list so browse the archives. It
was discussed at length in the BOF at CFUnited and that's where my
final decision was made, based on feedback from the attendees (about
40 FW/1 users).

Basically most FW/1 users find it either unnecessary or confusing -
depending on how experienced they are.

I originally thought I was providing a useful shortcut but it has
generated far more discussion than any other feature in the framework.
I've never really been entirely happy with implicit service calls and,
overall, it adds very little value.

> - The controller doesn't instantiate the model instance directly; it
> asks the service for the instance, but then populates it itself. It
> makes sense to me that populating gets done by the controller, since
> the service doesn't know about form/url/rc, but it's interesting to me
> that it doesn't create the model instance. Is that pretty standard,

There is no One True Way. Ask a bunch of devs and you'll get a bunch
of different answers. Do what works best for you and just be prepared
to change your thinking if you run into problems.

> - Lower level question, but if you do a redirect with a message, that
> ends up in rc, right? How do you access that from a layout, so there's
> standard infrastructure to display it?

rc.message

> No ORM, yet. If the structure of your model was that it threw
> immediately on invalid field assignments, that'd seem to limit your
> flexibility a lot; you'd have to try/catch each assignment
> individually. Is that a common strategy?

Again, there is no One True Way. Different developers do different things.

I've done it different ways in different applications. If I'm using a
typed ORM, I tend to validate form data outside the object and only
update the object if validation passes. If I'm using untyped objects,
I tend to populate them first and validate them internally. In
general. But even that's not set in stone.
--

Sean A Corfield -- (904) 302-SEAN

Railo Technologies, Inc. -- http://getrailo.com/
An Architect's View -- http://corfield.org/

Mike Rankin

unread,
Aug 30, 2010, 1:56:41 PM8/30/10
to framework-one
HaHa! That plural model has been rubbing my fur the wrong direction
for a long time. It's in some of the sample apps, like fw1 /
examples / userManagerAJAX.

...snip
> In FW/1, that's
> * Model: services and everything they touch
> * View: views and layouts
> * Controller: FW/1 itself and your controllers
>
> It's model (singular) not models. I've seen that plural notation
> somewhere recently and it's very jarring. Your application has one
.../snip

Mike Rankin

unread,
Aug 30, 2010, 1:57:43 PM8/30/10
to framework-one
Glad to see I'm not the only one that it bugs.

Sean Corfield

unread,
Aug 30, 2010, 2:33:36 PM8/30/10
to framew...@googlegroups.com
On Mon, Aug 30, 2010 at 10:56 AM, Mike Rankin <anody...@gmail.com> wrote:
> HaHa! That plural model has been rubbing my fur the wrong direction
> for a long time.  It's in some of the sample apps, like fw1 /
> examples / userManagerAJAX.

Ugh! I hadn't noticed that (I didn't write any of the user manager examples).

I'll open a ticket to clean that up.

Javier Julio

unread,
Aug 30, 2010, 2:42:50 PM8/30/10
to framew...@googlegroups.com
Haha sorry about that guys. I had created the UserManager and UserManagerAJAX demos. I guess I named it that way since the others were plural. Really strange I did that since I work in Flex and never use "models" but only the singular form. Feel free to change away! Don't like the plural form either. :)

> --
> FW/1 on RIAForge: http://fw1.riaforge.org/
>
> FW/1 on github: http://github.com/seancorfield/fw1
>
> FW/1 on Google Groups: http://groups.google.com/group/framework-one

Dave Merrill

unread,
Aug 31, 2010, 11:17:52 AM8/31/10
to framework-one
> On Mon, Aug 30, 2010 at 12:27 PM, Sean Corfield wrote:
> On Mon, Aug 30, 2010 at 7:11 AM, Dave Merrill wrote:
>> The distinction I'm after is between the roles of the service and
>> model.
>
> The services (in FW/1) are simply a gateway to your model. Really they
> are *part* of your model.
>
>> Models are smart value objects that contain data and business
>> rules for one object instance.
>
> That's very confusing terminology - probably why you're struggling here.
>
> FW/1 is MVC:
> * Model - all of your business logic and data
> * View - HTML display pages
> * Controller - control flow / traffic cop
>
> In FW/1, that's
> * Model: services and everything they touch
> * View: views and layouts
> * Controller: FW/1 itself and your controllers
>
> It's model (singular) not models. I've seen that plural notation
> somewhere recently and it's very jarring. Your application has one
> model, made up of all your (smart) domain objects and the
> orchestration code (usually 'services' of some sort). Orchestration
> code is needed for operations that don't naturally live in a single
> domain object.

Hmmm, the plural 'models' (from the directory naming in some of the
examples) does seem to be the confusion here, you're right. Are we
good with 'beans'? If the model(s) directory typically contains beans,
and all other domain-specific code is in services, my question is
pretty much answered: Beans contain data for one instance of a domain
object and methods pertaining to it, and in a typical FW1 app, roughly
speaking and in general, everything else goes in the service -- list
collection queries, queries for single-object data and code to create,
populate, and save bean instances. Closer?

(FWIW, sounds like a directory structure to mirror this organization
would be a 'model' directory containing 'services' and 'beans'
directories, probably the object factory, and maybe its config.)


This leads me to another question, apologies in advance if I'm behind
the OO-think curve here: It seems that the default FW1 strategy is
that services aren't called directly by controllers; service calls are
queued with \service(), then run all together. What's the advantage of
that sequencing model? It makes using the results of one service call
in another more awkward, and I'm unclear on what you get in return.

Clearly service methods should be self-contained and independent of
each other, in the sense that they deal only with passed arguments and
return explicit data, without examining or altering the surrounding
environment. Still, I'm used to controllers calling one or more model
methods, sometimes passing (partial) results of one to another (as
individual arguments). The various model method calls aren't coupled
directly, but the inputs to one may include data discovered by
another, with the sequence of methods to call and data to pass
orchestrated by the controller.

Is this a wrong-headed way to think about it? Although it's clear from
some of your examples that controllers can have services injected
which they can then call directly, clearly FW1 "wants" you to queue
service calls instead.


> If you haven't already, I'd recommend reading my "Beans and DAOs and
> Gateways, Oh My!" chapter in the Adobe ColdFusion Anthology (from
> Apress) or the original article in the FAQU: Do More Code Less issue.
> It covers several different ways of organizing model code in layers.

I read the FAQU article when it came out, will revisit it, thanks.

Thanks again for your time and input,
Dave

Sean Corfield

unread,
Aug 31, 2010, 12:54:04 PM8/31/10
to framew...@googlegroups.com
On Tue, Aug 31, 2010 at 8:17 AM, Dave Merrill <enig...@gmail.com> wrote:
> Hmmm, the plural 'models' (from the directory naming in some of the
> examples) does seem to be the confusion here, you're right. Are we
> good with 'beans'? If the model(s) directory typically contains beans,
> and all other domain-specific code is in services, my question is
> pretty much answered: Beans contain data for one instance of a domain
> object and methods pertaining to it, and in a typical FW1 app, roughly
> speaking and in general, everything else goes in the service -- list
> collection queries, queries for single-object data and code to create,
> populate, and save bean instances. Closer?

Yup - and remember that there's "service" in the general model sense
and *service* in the FW/1 sense. The latter is more of a facade onto
your overall model. It's an optional convenience - see below.

> (FWIW, sounds like a directory structure to mirror this organization
> would be a 'model' directory containing 'services' and 'beans'
> directories, probably the object factory, and maybe its config.)

Yup. Spot on. That's probably how I'll lay things out in FW/1 2.0 for
the examples - especially examples that use DI/1 (since it will most
likely support a convention that anything in a beans/ folder is
non-singleton).

> This leads me to another question, apologies in advance if I'm behind
> the OO-think curve here: It seems that the default FW1 strategy is
> that services aren't called directly by controllers; service calls are
> queued with \service(), then run all together. What's the advantage of
> that sequencing model? It makes using the results of one service call
> in another more awkward, and I'm unclear on what you get in return.

It's intended to create a clear separation of styles: controllers
interact with the framework and know about URL/form data etc, services
are pure data-in / data-out - and controller logic wraps service
calls:

controllers/section.startItem() - calls service() to queue up foo.bar,
something.else
rc.data = services/section.item()
rc.foo = services/foo.bar()
rc.other = services/something.else()
controllers/section.endItem()

That's the typical structure in a controller anyway if you have explicit calls.

Also bear in mind that the elements of the rc are available as named
arguments to services and they are in a strict sequence so:

service( 'foo.bar', 'foo' );
service( 'something.else', 'other' );

will allow for foo.bar( data ) and something.else( data, foo ) for example.

> Still, I'm used to controllers calling one or more model
> methods, sometimes passing (partial) results of one to another (as
> individual arguments).

Then don't use the implicit calls :) Manage your services directly in
controllers/section.init(fw) and call them explicitly:

rc.foo = variables.fooService.bar( data );

(or use a bean factory to manage services).

Nothing is *forcing* you to rely on the implicit service call model.
It's there as a convenience for the folks who like it and for those
where it simplifies their controllers. The whole implicit / queued
service call thing has proved to be the most confusing / controversial
aspect of FW/1 because people focus on it and think they *must* use it
- and that's simply not the case. It's an _optional_ convention for
those who want it. This confusion and controversy is why it's not
going to be the default in FW/1 2.0.

> Is this a wrong-headed way to think about it? Although it's clear from
> some of your examples that controllers can have services injected
> which they can then call directly, clearly FW1 "wants" you to queue
> service calls instead.

No. FW/1 doesn't "want" you to do it in a particular way. It offers
the ability to use implicit calls and queued services and it offers
the ability to manage all the services yourself (manually or via a
bean factory) and use explicit calls.

Hope that helps?

Dave Merrill

unread,
Aug 31, 2010, 4:54:29 PM8/31/10
to framework-one
> Also bear in mind that the elements of the rc are available as named
> arguments to services and they are in a strict sequence so:
>
> service( 'foo.bar', 'foo' );
> service( 'something.else', 'other' );
>
> will allow for foo.bar( data ) and something.else( data, foo ) for example.

But not something.else( data, foo.someField ), which was my specific
use case. Unless there's a way to pass foo as argumentCollection, but
it still feels kind of baggy passing a bunch of extra and potentially
conflicting extra fields.


> > Still, I'm used to controllers calling one or more model
> > methods, sometimes passing (partial) results of one to another (as
> > individual arguments).
>
> Then don't use the implicit calls :) Manage your services directly in
> controllers/section.init(fw) and call them explicitly:
>
> rc.foo = variables.fooService.bar( data );
>
> (or use a bean factory to manage services).
>
> Nothing is *forcing* you to rely on the implicit service call model.
> It's there as a convenience for the folks who like it and for those
> where it simplifies their controllers. The whole implicit / queued
> service call thing has proved to be the most confusing / controversial
> aspect of FW/1 because people focus on it and think they *must* use it
> - and that's simply not the case. It's an _optional_ convention for
> those who want it. This confusion and controversy is why it's not
> going to be the default in FW/1 2.0.

For my money, implicit service calls make sense when the controller
method would just be a pass-through, without any major technical
downside. I do understand the confusing-ness issue though.

Queued service calls appeal less to me. Without FW1, I've been very
explicit about passing data into service methods that return data,
which ends up passed into other service methods or to the view.
Turning that into a less transparent process seems like a negative,
and doesn't actually decouple anything from anything -- if something
needs the data, it has to get it from wherever it got put by something
that already ran. I get that I can ignore the queued model, and that's
probably what I'll do.

FWIW, I actually prefer explicitly passing data into views too, rather
than leaving it "laying around" in rc space. Along those same lines,
and to avoid conflicts in the variables space of singleton CFCs
without resorting to Local, I'd actually prefer it if views were
cfmoduled to, rather than cfincluded, and passing rc into them, either
as a single struct, or maybe more usefully, as attributeCollection, so
its members get exploded into individual attributes. Have you
considered that? It would break backwards compatibility, so it'd need
to be a non-default option.


> > Is this a wrong-headed way to think about it? Although it's clear from
> > some of your examples that controllers can have services injected
> > which they can then call directly, clearly FW1 "wants" you to queue
> > service calls instead.
>
> No. FW/1 doesn't "want" you to do it in a particular way. It offers
> the ability to use implicit calls and queued services and it offers
> the ability to manage all the services yourself (manually or via a
> bean factory) and use explicit calls.
>
> Hope that helps?

Very much, thanks,
Dave

> Sean A Corfield -- (904) 302-SEAN
> Railo Technologies, Inc. --http://getrailo.com/
> An Architect's View --http://corfield.org/

Sean Corfield

unread,
Aug 31, 2010, 10:34:10 PM8/31/10
to framew...@googlegroups.com
On Tue, Aug 31, 2010 at 1:54 PM, Dave Merrill <enig...@gmail.com> wrote:
> But not something.else( data, foo.someField ), which was my specific
> use case. Unless there's a way to pass foo as argumentCollection, but
> it still feels kind of baggy passing a bunch of extra and potentially
> conflicting extra fields.

Yup, so you're either going to need to take control of the services
and call them directly yourself in your controllers - the conventions
don't work for you there - or to treat the FW/1 services as a pure
facade onto your model (and have your 'real' services in the model/
folder, for example).

In that second case your something.else( data, foo ) method would turn
around and call realSomething.else( data, foo.someField );

> Queued service calls appeal less to me.

Well, that's the FW/1 way. When you call controller() you are telling
FW/1 to queue up calls to controller methods. When you call service()
you are telling FW/1 to queue up calls to services. This ensures the
request lifecycle is followed.

Again, if the conventions don't work for you, manage your services
directly and call methods explicitly in your controllers. That's why
FW/1 supports 'any' bean factory.

> FWIW, I actually prefer explicitly passing data into views too, rather
> than leaving it "laying around" in rc space.

I don't know of any CFML frameworks that provide that idiom
(interesting, tho' it is).

> It would break backwards compatibility, so it'd need
> to be a non-default option.

Views currently have access to any methods in Application.cfc and
framework.cfc directly - by design. So not only is it a big backward
compatibility issue, it goes against the simple design of FW/1.
--

Sean A Corfield -- (904) 302-SEAN

Railo Technologies, Inc. -- http://getrailo.com/
An Architect's View -- http://corfield.org/

Reply all
Reply to author
Forward
0 new messages