[Coldbox 4.1.0] Configure object mappings in ModuleConfig

57 views
Skip to first unread message

Nick

unread,
May 1, 2018, 12:33:23 AM5/1/18
to ColdBox Platform
Is it possible to configure object mappings in ModuleConfig and have all apps that includes the module to be able to use the mappings without having to remap them in the app's Wirebox?

For example, say I have an app called JohnnyBookshop, and it's including the Bookshop module.

In the Bookshop module there's a service called BookService: /modules/bookshop/services/BookService.cfc

Is it possible that, simply by defining the mapping in ModuleConfig.cfc, that the BookService be made automatically available for injections into JohnnyBookshop's models and handlers, like so:

Bookshop module's ModuleConfig.cfc
====================================================
function configure() {
        binder.map("bookService").to("bookshop.services.BookService");
}

It seems that right now I have to define the object mapping in JohnnyBookshop's Wirebox.cfc for it to work, like so:

JohnnyBookshop's Wirebox.cfc
====================================================
function configure() {
        map("bookService").to("bookshop.services.BookService").asSingleton();
}

Thanks for any help.


Eric Peterson

unread,
May 1, 2018, 10:50:29 AM5/1/18
to ColdBox Platform
What you are describing is definitely possible and is, in fact, the expected behavior.  With just the module and that `ModuleConfig.cfc` you should be able to inject `bookService`.

Without the local app WireBox mapping, what does the `bookService` inject?  Does it error?  Is it possible the module isn't being loaded?

A couple tips I'd point out as well is to 1) use `#moduleMapping#` in the `ModuleConfig.cfc` as the base path.  This avoids having to wait for mappings to be available. And 2) use a custom namespace for your mapping.  This makes it easy to identify it came from a module.  The default in ColdBox is to append an `@` with the module name.  With that change, your binding would look as follows:

```
binder.map("bookService@Bookshop").to("#moduleMapping#.services.BookService");
```

Brad Wood

unread,
May 1, 2018, 11:03:20 AM5/1/18
to col...@googlegroups.com
I'm a little confused why you're wanting to create mappings at all.  ColdBox automatically creates mappings for all model CFCs in all modules.  The name is "nameOfCFC@nameOfModule".  So you should be able to reference the mapping ID Eric mentioned ( bookService@Bookshop ) with no additional configuration at all.  

You can dump out all the mappings that WireBox already has like so:
writeDump( wirebox.getBinder().getMappings().keyArray() )

Thanks!

~Brad

Developer Advocate
Ortus Solutions, Corp 

ColdBox Platform: http://www.coldbox.org 


--
--
You received this message because you are subscribed to the Google Groups "ColdBox Platform" group.
For News, visit http://blog.coldbox.org
For Documentation, visit http://wiki.coldbox.org
For Bug Reports, visit https://ortussolutions.atlassian.net/browse/COLDBOX
---
You received this message because you are subscribed to the Google Groups "ColdBox Platform" group.
To unsubscribe from this group and stop receiving emails from it, send an email to coldbox+unsubscribe@googlegroups.com.
To post to this group, send email to col...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/coldbox/b275b487-28dc-431e-b396-d21eb8e22d26%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Eric Peterson

unread,
May 1, 2018, 1:32:51 PM5/1/18
to ColdBox Platform
One caveat to Brad's automatic model mapping is that it only happens for models in the module's `models` folder in the root of the module.  In your example your component was under a `services` folder in the root, so it would NOT be automatically picked up.  That's fixed by either an explicit mapping or by restructuring your folder layout to match the conventions.

Brad Wood

unread,
May 1, 2018, 1:49:00 PM5/1/18
to col...@googlegroups.com
Ahh, good catch Eric-- I hadn't noticed that.  I agree the easiest thing to do here is actually follow the conventions for models and put them under the models folder so they will get picked up automatically.  If there's some pressing reason why you can't do that, this one line in your moduleconfig would also do the trick:

binder.mapDirectory( packagePath='#moduleMapping#.services', namespace='@moduleName' );

That will recursive scan the folder and map all the CFCs based on their name with the module namespace added to it.  That's basically what ColdBox does behind the scenes for your models folder.

Thanks!

~Brad

Developer Advocate
Ortus Solutions, Corp 

ColdBox Platform: http://www.coldbox.org 


--
--
You received this message because you are subscribed to the Google Groups "ColdBox Platform" group.
For News, visit http://blog.coldbox.org
For Documentation, visit http://wiki.coldbox.org
For Bug Reports, visit https://ortussolutions.atlassian.net/browse/COLDBOX
---
You received this message because you are subscribed to the Google Groups "ColdBox Platform" group.
To unsubscribe from this group and stop receiving emails from it, send an email to coldbox+unsubscribe@googlegroups.com.
To post to this group, send email to col...@googlegroups.com.
Message has been deleted

Nick

unread,
May 1, 2018, 9:27:50 PM5/1/18
to ColdBox Platform
Thanks guys. Ok, just found out it's not the injection into handlers that failed, it's actually the AuditAdvice.cfc. I've got an advice set up in my Wirebox.cfc:

mapAspect("AuditAdvice").to("advices.AuditAdvice").asSingleton();

And in AuditAdvice.cfc I'm trying to inject BookService. I've tried both:
<cfproperty name="bookService" inject="BookService@Bookshop"/>
(with binder.map("bookService").to("#moduleMapping#.services.BookService");)

and:
<cfproperty name="bookService" inject="BookService"/>

Both are returning error:
The DSL Definition {JAVACAST={null},REF={null},SCOPE={variables},REQUIRED={true},VALUE={null},DSL={id:BookService},TYPE={any},ARGNAME={},NAME={bookService}} did not produce any resulting dependency
The target requesting the dependency is: 'AuditAdvice'

Brad Wood

unread,
May 1, 2018, 11:32:29 PM5/1/18
to col...@googlegroups.com
Your core WireBox config runs prior to any modules being loaded.  So the error message is correct in that that mapping doesn't exist yet at the time it's being asked for.  In ColdBox 5 we've make wirebox.cfc an interceptor so you can add in an afterConfigurationLoad method  where you add mappings that are dependent on modules being loaded.  Another workaround is to use a provider for the injection that doesn't exist yet so long as as it won't actually be used until after the module has loaded.

inject="provider:mappingThatDoesNotExistYet"

That will defer the actual resolution of the mapping ID until the point where you try and use it which will likely be after the framework is up and processing requests.

Thanks!

~Brad

Developer Advocate
Ortus Solutions, Corp 

ColdBox Platform: http://www.coldbox.org 


--
--
You received this message because you are subscribed to the Google Groups "ColdBox Platform" group.
For News, visit http://blog.coldbox.org
For Documentation, visit http://wiki.coldbox.org
For Bug Reports, visit https://ortussolutions.atlassian.net/browse/COLDBOX
---
You received this message because you are subscribed to the Google Groups "ColdBox Platform" group.
To unsubscribe from this group and stop receiving emails from it, send an email to coldbox+unsubscribe@googlegroups.com.
To post to this group, send email to col...@googlegroups.com.

Nick

unread,
May 2, 2018, 1:06:26 AM5/2/18
to ColdBox Platform
Thanks. Looks like the provider approach works.
Reply all
Reply to author
Forward
0 new messages