On Thu, Oct 8, 2009 at 8:18 PM, Sean Corfield <[email protected]>wrote:

>
> On Tue, Oct 6, 2009 at 3:28 PM, John C. Bland II <[email protected]>
> wrote:
> > 1) Using MG, ColdSpring, and Transfer
> > There are two or three places where a datasource is set. This is
> > pretty counter-intuitive (change N places to tweak the datasource
> > name). Did I do something incorrect or is this simply going to happen?
>
> I'd expect to only put it in the Transfer config and then expose it
> via factory-bean definitions in ColdSpring should it be needed
> elsewhere in the application (do you need the datasource name anywhere
> really?).
>

Sometimes I want to perform SQL beyond the capabilities of the ORMAdapter's
list() method and Transfer Query Language (TQL); in such cases I go back to
using the cfquery tag (or maybe cfstoredproc). Of course, I encapsulate the
code in singletons under ColdSpring, but I need to somehow pass the
datasource information to their corresponding bean definitions.

Some of the Model-Glue sample code that's available requires the datasource
information to be provided separately from the ORM information for such
beans. The most notable case is the usermanagement actionpack bundled with
Model-Glue 3. I consider such forced duplication to be poor practice.
Fortunately the actionpack abstracts out the datasource information to its
own bean, and herein lies our solution: an adapter CFC that implements the
abstracted datasource interface for our ORM service. The following is a
datasource adapter I wrote for Transfer:

<cfcomponent output="false" hint="I am a Datasource CFC adapter for a
Transfer ORM Factory."> <cffunction name="Init" access="public"
output="false" hint="Constructor">
<cfargument name="transferFactory" type="any" required="true" />
 <cfset variables.transferDatasource =
arguments.transferFactory.getDatasource() />
<cfreturn this />
</cffunction>

<cffunction name="GetDSN" access="public" return="string" output="false"
hint="Get property: DSN">
<cfreturn variables.transferDatasource.getName() />
</cffunction>
 <cffunction name="GetUsername" access="public" return="string"
output="false" hint="Get property: Username">
<cfreturn variables.transferDatasource.getUserName() />
</cffunction>
 <cffunction name="GetPassword" access="public" return="string"
output="false" hint="Get property: Password">
<cfreturn variables.transferDatasource.getPassword() />
</cffunction>

</cfcomponent>


Writing an equivalent datasource adapter for Reactor should be just as
simple.

Here is the ColdSpring XML for feeding the datasource information from a
Transfer ORM service to a queryGateway bean:

<bean id="queryGateway" class="myproject.model.data.QueryGateway">
<constructor-arg
name="datasource"><ref bean="datasource" /></constructor-arg>
</bean>

<!-- Use an alias so we can easily switch between different datasource
adapters (or even a plain datasource CFC) -->
<alias alias="datasource" name="datasource.Transfer" />

<bean id="datasource.Transfer"
class="myproject.addons.transfer.DatasourceAdapter">
<constructor-arg name="transferFactory"><ref bean="ormService.Transfer"
/></constructor-arg>
</bean>


With this approach, not only do we avoid duplication of the datasource
information, but our queryGateway is not tied to any specific ORM service
implementation.

I find this pattern to be quite useful, and would like to see it (or
something like it) bundled with Model-Glue at some point in the future.


>
> > 2) Transfer vs Reactor
> > I know...this is a subjective question but I noticed the docs made
> > mention to Reactor for scaffolding. More-so curious as it applies to
> > MG here and not so interested in a "mine is bigger" convo.
>
> MG is ORM agnostic so you can pick whichever you want and it will "just
> work".
>

A semantic nitpick: MG's ORM functionality is implementation-independent,
not agnostic. Implementation-independent means that MG depends only on an
abstract ORM interface, so the chosen ORM implementation can be replaced
with a different implementation without affecting your MG code.
Implementation-independent is the formal term for "pick whichever you want
and it will just work".

Agnostic means that there is no dependency at all, not even to an abstract
interface. We want our ORM adapter to be framework-agnostic; this means that
we do not want the ORM adapter to make any calls to framework objects or
services. The key difference between this and implementation-independence is
that the ORM adapter should still work even when there *is* no framework
(hence the term agnostic).

Of course, something has to perform the communication between the framework
to the ORM adapter. In Model-Glue, that is the job of the
GenericOrmController CFC provided by the framework. Any other framework
wanting to make use of a framework-agnostic ORM adapter would therefore need
to provide its own specific controller.

Brian Kotek's presentation on framework-agnostic models explains in detail
why you should implement your model CFCs in a way that never references any
framework objects or services, and encapsulate all framework-to-model
communication in your controllers. The growth of Ajax frameworks and the
Flex and AIR platforms since he first made the presentation makes this
design principle more important than ever.

Cheers,

-- Dennis

--~--~---------~--~----~------------~-------~--~----~
Model-Glue Sites:
Home Page: http://www.model-glue.com
Documentation: http://docs.model-glue.com
Bug Tracker: http://bugs.model-glue.com
Blog: http://www.model-glue.com/blog

You received this message because you are subscribed to the Google
Groups "model-glue" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/model-glue?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to