RE: [coldbox:17854] [Coldbox 3.5.3] - Wirebox Question about OO models and how they get populated.

Thanks for the feedback.

It sounds like to me, based on that, I will be able to stop using custom object factories. So how do I do that?

I’m not sure how to answer that question. I think your confusion mostly comes from the fact that you call your services object factories. At some level, I also interrogate my UserService when I want it to load an instance of a user object, but I don’t consider it an object factory per se-- I think of it more as the API to my application. Internally, the service method asks WireBox to provide it with a user object, which it then calls some methods upon to load data into that user. Afterwards, the service method may consider implementing caching of that object for later use. I see an object factory as a class that abstracts the creation of the object as well as the actual full component path and gives that object everything it needs to do its job. My services do much more than that as they actually begin calling methods on my objects, loading them with data, giving then state and changing that state as well as interacting with the other moving parts of my application. If I were to guess, you use the term object factory in a different light than our docs use it.

The coffeshop example shows the different ways to do injection which is great. But object factories are more than just that. They are about pulling in all the resources to return to you an instance of a object.

But that is what the example does. in that code sample, a CoffeeShop has a single dependency of an expressoMachine.

But the example never shows how that part would work with wirebox.

Look at the property line of code at the top of the CoffeeShop class that looks like this:
property name=“espressoMachine” inject=“id:espressoMachine”;

That is all you need. Now, if you were to create an instance of the CoffeeShop like WireBox.getInstance(“CoffeeShop”), that CoffeeShop object will contain a reference to the expressoMachine class in its variables scope.

It doesn’t really show you how you would stop using object factories as stated in bullet 2 up above.

Lol, I’m not sure what to tell you. It also doesn’t tell you how to not use PHP… the code is what it is. All that is shown is what is necessary to inject a reference of one object into another.

but for a person trying to learn what wirebox is and how the way you are used to working with objects translates to it… it can be a little frustrating.

I agree. That’s also why I wouldn’t recommend trying to read the full docs to get started. It would kind of be like reading the CFML language reference straight through to learn CF. I’d recommend watching a couple presentations on getting started and checking out our sample apps. Here’s a couple recordings of Luis demoing WireBox that you may find helpful:

http://experts.adobeconnect.com/p52099674/

http://vimeo.com/album/2017304/video/46480379

I just wish that it showed some examples that didn’t use populateModel ()

If it helps, replace calls to populateModel() in your head with a list of setter calls; one for each property.

maybe another model with a little bit more complex structure. For example if Contact.cfc contained a PhoneNumber object. Where would the responsibilities lie for populating it and how does that work with Wirebox DI.

Well, we do try to steer clear of getting too complicated in the docs-- then people will tell us they’re too deep :slight_smile: That might be a good idea of a new sample app-- one that shows more interaction between models. I think one of the reasons we’ve stayed away from showing too much of that is because it’s outside of the framework and up to the developer to decide. If your models use composition (i.e., a contact object has a phoneNumber object) that’s up to the developer to choose how they want to implement that. WireBox doesn’t dictate how you want to do it, it’s just there to help create and autowire the phoneNumber object when you’re ready for it.

For what it’s worth, I can tell you how I do it-- but everyone on this list probably has their own favorite (and different) solution.

  1. Firstly, my models all extend a base bean class with a generic get() method.

  2. When you get the phone number for a contact, it would look like this: contact.get(“phoneNumber”).

  3. Internally, the base class keeps a list of what properties have been loaded into the contact object.

  4. The first time I call contact.get(“phoneNumber”) my base class looks for and automatically calls a lazyLoadPhoneNumber method. This method asks the contactService (which has been wired in via mixin injection) to load up the phoneNumber object and does something like so:

  5. this.set(“phoneNumber”,contactService.getPhoneNumber(contactID = this.get(“contactID”)));

  6. The contactService has WireBox injected into it and calls something like WireBox.getInstance(“phoneNumber”).read(contactID = arguments.contactID)

  7. The phoneNumber bean has the phoneNumberDAO autowired into it and the read() method delegates out the DAO to get a result set, and then sets the data into the bean.

  8. After that, the phoneNumber object is saved in the Contact object as long as the Contact object is kept in memory.
    Now, honestly I wouldn’t want to put all that in the docs because it’s just how I personally handle loading composed objects in my application. There’s sooo many things I could do differently and we don’t even try to steer you down one path or the other in the ColdBox docs.

As far as the feelings of frustration trying to figure everything out-- don’t worry. it will, as Mike Craig said, “get better” :slight_smile: OO and DI engines are not a simple matter and there is a lot to learn. Much of what you learn is that there’s many ways to do something and they all have advantages and disadvantages. The best way I’ve found to take it is to dive in and start trying stuff and ask lots of questions.

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Just to chime in an additional comment that is purely experiential, personal and, I hope, relevant…and simply because I can.

Coldbox, the Coldbox Evangelists, Luis’ team and Ortis Solutions have really pushed the envelope of what ColdFusion can really be capable of by capitalizing on what it already there. I have often shared in the frustration of “getting started” and truth be told, this is probably the forth time I have tried to pick up this framework in the last two years…those frustrations kept me away.

I might argue I was not ready, I might argue Coldbox was not ready. For every kudo I can give that list above I can also tell you I have been pissed off, angry, disappointed in or about…the list is endless. Humans have flaws, code has bugs, but the effort is the thing. Most (if not all) frameworks are free, but the time to develop, the extensive documentation and the unbelievable support make it WORTH that effort.

But change is not a quick thing and is seldom comfortable or easy. “I do it this way”, “I think it should be this way”, “Why the hell are you doing that”, “This just doesn’t make any sense”…do any of those sound familiar? This, like many things for me at least, is an exercise in patience, tolerance and cooperation. It never helped that I consider myself to be pretty smart as it tends to fail me as a measure of anything meaningful. I remember a paraphrase that even caveman though fire was magic at first.

We can say start slow, don’t read it all in one sitting, try and try again…and that would be very good advice…but don’t do what I did and stop before you even get a chance to start. In the end, the effort will make you a better developer, EVEN IF you decided not to adopt Coldbox.

It can still be frustrating, but it is amazing how the effort has paid off and I am still awestruck by how much flexibility some of the simplest things have offered.

[ end philosophy and opinion ]

Mike