Wirebox initWith() - pass object by map reference

Hi group,

I’ve currently got the following in my Wirebox config…

mapPath(“model.user.UserGateway”).asSingleton().initArg(name=“coldbox”,value=getColdBox());
mapPath(“model.user.UserService”).asSingleton()
.initArg(name=“coldbox”,value=getColdBox())
.initArg(name=“gateway”,ref=“UserGateway”)
.initArg(name=“objectType”,value=“User”);

… but what I’d like to do is swap those initArgs for a single initWith instead. The 1st and 3rd arguments aren’t a problem but I can’t find anywhere in the WB documentation on how I can pass the Gateway through its reference.

Any help is appreciated.

Cheers,
James

James,

I know this is not an answer, but I am curious if the path model in your code is the model of Coldbox. Is there any reason why you are mapping them like this?

Personally I would be more inclined to let Coldbox auto wire them, and use DI within the model.

No worries Andrew. Yeah it's the CB model and personal preference really.

Doing it through config I find easier to manage and see everything in one place. That and I'm not keen on bogging the model down with extra metadata if it can be avoided.

It's more to manage if / when we started swapping out frameworks and clutter if we use the model outside of CB.

Cheers
James

Yeah I am the other way, the less manual configuration needed.

I’m not as familiar with the constructor argument mapping since I tend to just autowire everything in my components. I dug through the code and it looks like what you are asking for is not possible.

initArg() is very flexible because it allows you to define your dependencies by reference (mapping ID), DSL, or value. However, initWith() assumes that the arguments you are passing in are already-evaluated values.

If you look in the initWith method of /coldbox/system/ioc/binder.cfc, you will see it calls currentMapping.addDIConstructorArgument and passes in the arguments as a value.

The only way initWith could give you the option of specifying if each argument was a mapping ID reference, DSL, or value, would be if we rewrote it to accept a struct for each argument that specified instead of just single name/values. So basically, initWith() is just a shortcut for initArg() that can only be used when passing in straight values.

I even tried to see if you could eager init your dependency and call getInstance() right there in the config, but it errors out as WireBox has not finished loading up yet.

I’ll try to update the docs to make this more clear.

Can you describe to us why you are wanting to switch from initArg() to initWith()?

Thanks!

~Brad

Thanks a lot of the detailed response Brad. I thought someone might come back and say something like this.

I ended up diving into the code myself trying to work it out but couldn’t find anything obvious so thanks for the confirmation.

My main reason really was to have a cleaner syntax. I just think if you’ve got a method that takes in a lot of arguments the use of initArg for each could start to get a bit long-winded while, as you say, passing an argument structure into a single InitWith would allow for a cleaner separation and more flexibilty.

So this…

argStruct = {

coldbox = getColdBox(),

gateway = getInstance(“UserGateway”),

objectType = “User”

};

mapPath(“model.user.UserService”).asSingleton().initWith(argumentCollection = argStruct);

… over this…

mapPath(“model.user.UserService”).asSingleton()
.initArg(name=“coldbox”,value=getColdBox())
.initArg(name=“gateway”,ref=“UserGateway”)
.initArg(name=“objectType”,value=“User”);

Cheers again,
James

Which is why the other way I mentioned is far better, because when you make changes to that component, especially if you are defining arguments like this, means you are making changes in 2 places. I personally hate making those sort of decisions, and why it is a personal choice of mine to not go down this route.

In development in can also led to productivity downtime while you try to also work out why it is not working, compared to it just working if you DI in the component itself…

Just something to take into consideration.