[ColdBox 3.81] DI question.

Hey all,

I'm in the process of taking an older non MVC based app and refactoring into ColdBox.

In the legacy app we have quite a few objects that get stored in the application scope. In my refactoring I'm loading these objects through Dependency Injection instead.

This just feels like a better approach to me but a colleague was asking me why I was no longer creating these objects in the application scope and if DI might actually be doing this when classes are injected. I wasn't completely sure how to answer him.

I guess my questions are:

1. Is there any reason to store objects in the application scope or in ColdBox terms the ApplicationStorage plugin if I inject objects?

2. When using DI do these objects in fact get stored in some type of persistent manner?

I've built quite a few ColdBox apps in the past and in my experience I've never had a need to create objects that are stored in application scope.

But since our current legacy app has so many objects in the App scope I just want to make sure there won't be too much overhead if I'm injecting too many classes.

Thanks,

Ben

> 1. Is there any reason to store objects in the application scope or in ColdBox terms the ApplicationStorage plugin if I inject objects?

There are certainly reasons to persist objects in a “scope”. The length of the scope depends on what that object is and what it’s doing. By default, single-use objects are called “no scope”, or transient. Many people think the only other scope is singleton, but that’s not true. You can have objects that need to live for the live of a request, session, application, you name it… The two main reasons for persisting an object are:

  1. To save state. (Imagine a shopping card object that lives for a user’s session and stored everything in their cart)
  2. To avoid unnecessary creation. Services, DAOs, or utility classes may not store any state or instance data, but there’s no sense in re-creating them over and over.

So, getting back to your original question-- you can manually put stuff in the ApplicationStorage plugin if you want, but the whole reason you’re using a DI/ioc container is “Inversion Of Control”! That’s what the ioc stands for and it means you shouldn’t have to worry about how your objects were created, where they came from, what dependencies they need, or how long they’ll live. Just ask WireBox for them, and it’ll take care of the rest. If you’re creating an object and manually setting it into a scope you’re doing it wrong-- well, you’re at least doing more work than you need to.

> 2. When using DI do these objects in fact get stored in some type of persistent manner?

This is sort of a double question. if you inject object A into object B, then yes A gets stored somewhere— namely in B! B will have the same hard reference to A as long as it lives. Never inject an object with a scope shorter than the object being injected into. This is called scope widening injection. There more info on that in our docs.
So maybe you mean does object A get persisted anywhere ELSE? That’s entirely up to you :slight_smile: By default, WireBox will treat all objects as transients and a new version will be created every time you request it. Specifying a scope for an object is easy and my favorite way is via component annotations:

// This will live for the life of the injector
component singleton {}

// This will live for the life of the session
component scope=“session” {}

// This will live in the default cache for 20 minutes
component cache cacheTimeout=20 {}

It’s very easy to configure scopes for your components. Just ask WireBox for them and it will take care of everything. Here’s some more docs on that.

> I’ve built quite a few ColdBox apps in the past and in my experience I’ve never had a need to create objects that are stored in application scope.

That’s probably because you’ve never created a true domain model where objects represent real life things with behaviors and state that mutate over time. Or perhaps your sites have just been very simple. Don’t worry though, it’s a natural progression to start using CFCs for simple code reuse and utilities. You can always get fancier over time.

> But since our current legacy app has so many objects in the App scope I just want to make sure there won’t be too much overhead if I’m injecting too many classes.

I’m not sure what you’re asking, but the “overhead” of injecting a dependency only happens once when the object is created. It’s just a matter of placing variables in variables or this scope that point to the dependency. And if the dependencies are singletons (services, DAOs, etc) then they only get created once. Don’t worry about premature optimization for now. Just create a domain model that’s self contained (free of encapsulation-breaking references like application.foo) and go from there.

The code in a CFC’s methods should ONLY reference variables that came from:

  1. Arguments
  2. The CFC’s instance data (state stored in the variables scope and shared by all methods)
  3. Injected dependencies

Then your code will be easier to test and debug. Here’s a ref card with an overview of WireBox functionality too.

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

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

Brad,

Thank you for your thorough explanation. This definitely helps to answer some of the questions I had.

I need to read the WireBox docs more thoroughly so I have a better understanding of how it all works under the hood so to speak, but I think I get the gist of it.

Thanks again,
Ben