How to pass in required constructor arguments whne using dependency inject?

I am hoping this is an easy one for someone out there. I can’t seem to find the proper syntax for passing init arguments when doing a dependency inject with properties.

For example, my handler is injecting the following:

property name=“myService” inject=“somethingMyService”;

the somethingMyService model requires an argument upon init(). Is there a way to pass that argument?

Thanks in advance for your help.

There are several ways to handle this. The quickest and easiest way is for the name of init parameter to match the name of the WireBox mapping that needs to be injected. Note, WireBox can map not only CFCs, but also constants, settings, java objects web services.

So let’s say your init looks like this:

/**

  • @fooService.inject fooService
    */
    function init( required fooService ) {}

Now, as long as WireBox knows what “fooService” is, it will inject it for you. In fact, I actually think the inject annotation is optional as long as the actual mapping being injected matches the name of the parameter.

Honestly I don’t use constructor args, I just stick the properties in my CFC. One benifit is mixin injection automatically puts the dependency in my variables scope for me instead of me need to do this extra legwork in my init

variables.fooService = arguments.fooService

The other way to declare constructor args is in /config/WireBox.cfc with the map().to() DSL. I personally try avoid explicit mappings and like to allow the metadata of my CFCs to speak for itself.

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

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

Hello Brad,

actually I have the same problem and your answer is not clear enough for a Coldbox newbie like me. :wink: I think I know hove to set argument variables to a Component, but how can I handover the variables key, and language to the init function? How is it possible with the “inject” syntax in the handler? I search around the coldbox manua, google and other things for several hours, but right now I have no idea.

I know that I can use “property” for key and language in the module-cfc-File a then the setter for the values, but i would like to have right in one line of code like

myAwesomeService = new models.MyAwesomeService.init( key=“4512-32e23-23423”, language=“de-de” );

Main.cfc (Handler)

`

component extends=“coldbox.system.EventHandler”{

property name=“myAwesomeService” inject=“MyAwesomeService”;

function index(){

}

}

`

MyAwesomeService.cfc (Model)

`

component singleton accessors=“true”{

MyAwesomeService function init( key , langauge ){

variables.key = arguments.key;
variables.language = arguments.language;

return this;

}
}

`

I think there is some missing context here preventing me from giving you a definitive answer. Are all instances of your service the same everywhere in your app, or do you have difference init params you want to pass in different places? Or perhaps, you want the “key” and “language” to be different potentially on every page request?

As your example stands now, you have a singleton (meaning your entire app shares a single instance of the service CFC) which has hard coded inputs which would sort of remove the necessity of even having the inputs in the first place, but without knowing the real life use case of them I can’t recommend an approach.

If the key and lang variables are truly static values that never change, but you simply want to externalize them from the CFC for organization, then put them in ColdBox settings and just inject them into your service and remove the init args entirely.

If key and lang are different in some contexts, you need to define those contexts and likely not make them instance variables of the service or not have your service be a singleton and create a new instance every time the context changes. Sorry, that may seem like a circuitous answer, but I really can’t be more specific without knowing more of your use case.

I think you allready helped me with our questions! :wink:

The service should be a single instance which should be shared by the complete app. So the key and the language is only necessary for one time. But I thought of reuseability of the service in other projekts or in a coldbox module, I don’t know yet. Therefor I want to leave the two params outside the cfc and when I create an instance of the service i give them as a “init-config”. Maybe there is another way to set a configuration for a service in the ColdBox way. You mentioned “WireBox mapping”. I found the Coldbox.cfc in the config folder maybe there is the best place to store the parameters?

best regards
Michael

My recommendation is to create two keys for those values in your ColdBox.cfc in the “settings” struct. Then simply inject them into your CFC like so:

property name=“mySetting” inject=“coldbox:setting:mySetting”;

That way you have the settings externalized and avoid any need for messy constructor args.

You mentioned a module. If you were to wrap up this CFC as part of a distributable module, then you could make the setting be a module setting which would still be overridable at the application level. Just a thought for future portability.

I allready found the settings struct in the Coldbox.cfc but I didn’t realise how to get the settings from there. I found a function called getSetting() in the Coldbox component but I thought this is not the way Coldbox want me to do that. :wink: I must dive deeper into wirebox in the future!!

Thank you very much!!!

Michael

You can use getSetting() from any component which extends the framework super type

  • interceptors

  • handlers
    or any CFM that is rendered by the framework:

  • views

  • layouts
    Your models however (services, DAOs, beans, etc) don’t have any of those handy UDFs available to them out the box. You can inject the Coldbox controller and call its getSetting() method, but it’s much more intuitive to simply ask WireBox to inject those settings for you via a property.