If You Use ColdSpring, Use Its Full Potential
I noticed a blog post recently called Building ColdFusion services with ColdSpring and Reactor, part 3 and wanted to comment about it.
A side note to Tom and Rachael (owners of that blog). You've decided to force visitors to register before they can comment. Which is quite a pain, but I tried to do it nevertheless. My password was never emailed to me. I requested another password, and it never arrived either. Please do something about this as it was pretty annoying to go through the process and still not be able to comment!
In this blog entry, and the others in the series, the writer is talking about using ColdSpring. This latest entry shows ColdSpring being used with Reactor. However, in my opinion they are only using ColdSpring for a portion of what it is really meant to provide.
The Reactor example has them injecting the Reactor factory (for some reason they have named it "ReactorGateway" which is a rather confusing choice) via a public setter. But then, other code is calling createGateway() on the Reactor factory to get a Gateway instance.
I think a better approach would be to use ColdSpring to get a Gateway instance and inject it for you. You can do this using the ColdSpring factory method support:
<bean id="UserManager" class="path.to.UserManager"> <property name="UserGateway"> <ref bean="UserGateway" /> </property> </bean> <bean id="UserGateway" factory-bean="reactorFactory" factory-method="createGateway"> <constructor-arg name="objectAlias"> <value>User</value> </constructor-arg> </bean> <bean id="reactorFactory" class="reactor.reactorFactory"> <constructor-arg name="configuration"> <ref bean="reactorConfiguration" /> </constructor-arg> </bean>
This way, your manager doesn't have to know anything about the Reactor factory, or where this gateway is coming from. The same advice would apply to the previous entry in that blog series, where the Manager is making calls directly to the ColdSpring bean factory. Instead of calling getBean() for UserManager and Logger, inject these at object creation.
I think the only time I would access the ColdSpring factory directly is if I were creating a transient CFC. And even then, I'd probably use ColdSpring to inject a factory object into the necessary CFC and use that to create and return my new object. This is because the logic to correctly create and return a transient CFC (often a business object) ususally requires actual CFML code to perform (conditional statements, etc.)
Anyway, I just wanted to comment on this post and since I couldn't do it at Tom and Rachael's site I decided to do it here. If you're using ColdSpring, use it to its full potential. Don't stop at just injecting Reactor or ColdSpring into other components. Leverage the complete dependency management features of it. I think you'll find it makes your code more flexible.




Generally speaking, the goal of a bean container is:
1. configure and instantiate Singletons
2. inject Singleton references into other Singletons
3. do #1 and #2 in the right order to resolve dependencies automatically
Usually these Singletons are:
1. Immutable
2. Persisted for the lifetime of the application
3. Unaware of the bean container
4. Instantiate objects with mutable state
Sorry you had problems registering, as I see from your own blog you ask for the exact same information as I do in order to deal with comment spam (but without an email confirmation step). It's a shame to enforce this pain on everyone because of a few idiots, but that's the way it is.
If you get in touch with details of your account, I will see what happened to it. If you are the relatively new user brian<3 numbers> at a popular webmail service provider, the email with the validation code was sent 9pm Monday. Maybe your provider bin'ed it as spam ?
On to the code then :-)
Yes, calling the injected Reactor Factory 'ReactorGateway' is confusing, I've altered that to make it clearer, cheers.
You make a valid point about injecting the Factory vs. injecting the gateway itself. We've found it more obvious to people getting started with OO to inject the Factory. The articles started being written many months ago, however, and things have moved on. I will try and cover some of the alternatives (such as your idea) and problems at the end of the series, when I've finished outlining one way in which you can build a tiered SOA.
That's one of the key themes of the series, actually. We took some ideas, and we built something. It might not be 100% right, it might not be always the best bits we've chosen to show you. But it's a good set of ideas (we think so anyway !), and helps give people a leg up into enterprise-class architecture with ColdFusion
@Matthew: I'm not sure why you say '[have] Coldspring inject itself into an object'. I certainly wouldn't normally advocate that, and don't see anything like that in Brian's article.
Don't worry, I've had many times where I wrote or did something and then looked back on it (even only a few days or weeks later) and wondered why I did something a certain way. I think the articles are very good, I just wanted to make sure that other readers (and you if you didn't know) were aware of the additional things ColdSpring can do. I highly doubt that most people are taking full advantage of it, since it can take some time to really "get" what a DI engine brings to the table. Whatever you do, keep those articles coming! The point of my response was definitely not to single you out or ding you for doing something "bad", but to expand on the topic to make sure others were aware of the additional capabilities of ColdSpring.
<cffunction name="save" ...>
...
<cfset var bean = beanFactory.getBean("beanName")>
...
<cfreturn variables.DAO.save(bean)>
</cffunction>
Would this be a bad (inflexible) approach? My thought is that I could switch bean factory frameworks but my objects would always be dependent upon "a" framework.
Line 623 Error:
'this.subscriber_email.value' is null or not an object.
I'm using IE6.