RE: [coldbox:15764] Re: Wirebox initWith() - pass object by map reference

> Why does initWith() have to support everything initArg() does though?

Well, that’s essentially what you’re asking for in this thread, right? InitWith() currently is a shortcut that only allows values to be passed in. You are asking us about expanding the behavior of initWith() to do things that iniArg() does-- namely passing in mapping ID references. If we were to consider that, we would implement a holistic solution that also included DSLs.

> It doesn’t seem to have the same behaviour unless there is something buried in WB that requires it to be like that.

I’m not sure if I follow that statement, but initWith() and initArg() are both wrappers that call the addDIConstructorArgument() method on a mapping object in the binder. addDIConstructorArgument() will accept 3 types of contructor args-- a static value, a mapping ID (ref), or a WireBox DSL. InitArg() can do any one of those three, but only adds one constructor argument at a time. InitWith() only works for static static values, but let’s you add as many constructor arguments as you like. I agree that it’s a little weird that initWith only supports 1/3 of the possible types, but if we were to rewrite that method, we’d make it support 3 of 3, and not just stop at 2 of 3.

> Could you not just pass through an argument struct in the same way you would normally call a method and let it handle the correct type?

No. What if you passed in the string “foobar”-- how would WireBox resolve that when it came time to build the mapping? “foobar” could be an ID reference to another WireBox mapping called “foobar”. It could be a custom builder namespace that required a foobarBuilder to supply it. It could also just be the static string “foobar” as in a simple setting or data source name. WireBox has no way of knowing at that time, and doesn’t make assumptions about what you mean. It relies on you telling it how it should use the variable you passed in when it comes time to build the mapping. For those reasons you can’t just pass in strings and let the binder handle the correct type.

> Now if I had a method available to m**e to get an instance of the Gateway then I’d be ready to go :slight_smile:

Well, like I said the other day, there’s a chicken and egg problem where WireBox isn’t up, running, and ready to build mappings until after it’s processed the config file. That means you can’t get instances of mappings while the config file is being processed. Now you could add mappings programatically to the binder after WireBox loads, but it would only work for passing in singletons.
For instance, if a constructor arg to the transient “car” was another transient “driver” object, all cars would incorrectly get the exact same driver object if you configured an instance of driver as a static value for the constructor args for car.

So I think the take-away answer is this: What you asking for is possible (a single binder method to add multiple constructor args of any type), but it would require a syntax similar to what I showed in my last E-mail. If we did create a method, I would actually recommend it have a new name such as initArgs (plural). I’m not very convinced though that such a method would have a significant benefit over multiple chained calls to initArg().

Good questions. Hopefully that helps explain.



ColdBox Platform Evangelist
Ortus Solutions, Corp

ColdBox Platform:

Thanks again for your time Brad, this is great and you’ve given me a much better understanding of how it’s all put together.

Much appreciated