Coldbox 3.7.0: Modeldecorator depending on rc.Service

Hi everbody,

I have been trying to inject a Service depending on a rc variable. My actual setup looks like this.

+ handler
...
+ modules
  + api
    + handlers 
      + question.cfc
    + model
      + QuestionService.cfc
      + AnotherService.cfc

After readin http://wiki.coldbox.org/wiki/Models.cfm and http://wiki.coldbox.org/wiki/WireBox.cfm i tried to inject AnotherService in the init function but couldn’t get it done, what am i doing wrong.

`
component name=“Question” extends=“core.handlers.CommonRest” {
property name=“QuestionService” inject=“QuestionService”;

//REST Allowed HTTP Methods Ex:
this.allowedMethods = {
index=‘GET’,
info=‘GET’
};

function init(event,rc,prc) {
injector = createObject(“component”,“coldbox.system.ioc.Injector”).init();

         QuestionService = injector.getInstance("model."&rc.Service);

}

function index(event,rc,prc) {
response = QuestionService.list(rc.userUid);
prc.response.data = response.response;
}

function notinset(event,rc,prc) {
response = QuestionService.notinset(rc.userUid,rc.setUid);
prc.response.data = response.response;
}

function info(event,rc,prc){
prc.response.data = {name=“QuestionService”};
}
}
`

as always any help is very appreciated.

greets

You need to use the onDIComplete for models and configure() for interceptors.

But that will not solve your other issue, you need to realise that RC scope is defined at request time. Which means you are better of using getModel() when you need it rather than the way you are currently doing it.

Pretty much everything Andrew said plus-- don’t create a new injector instance in your handler. Just inject the one that comes with ColdBox like so:

property name=“wirebox” inject=“wirebox”;

When an object is created, things happen in this order:

  1. yourObject = createObject(“path.to.yourObject”);
  2. yourObject.init()
  3. injector.autowire(yourObject);
  4. yourObject.onDIComplete();
    As you can see, you can’t use injected properties in the init() since it happens before autowiring. Use onDIComplete() instead. Also, to reinforce what Andrew said, there’s no rc argument to your init function. Init is called outside of the normal request lifecycle and it has no arguments unless you define them and ask WireBox to pass them in…

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

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

I still seem to missing something since I’m a complete newbee to coldbox.

`
component name=“Question” extends=“core.handlers.CommonRest” {
property name=“QuestionService” inject=“QuestionService”;
property name=“AnswerService” inject;

function info(event,rc,prc){
prc.response.data = AnswerService.success(“jaskldf”);
}

function OnDiComplete(event, rc, prc) {
AnswerService = getModel(“core.modules.api.model.AnswerService”);
}
}
`

This should work right? But i get an Exception.

Application Execution Exception Error Type: Expression : [N/A] Error Messages: Variable CONTROLLER is undefined.

There may be some confusion here. The following two lines are redundant:

property name=“AnswerService” inject;
AnswerService= getModel(“core.modules.api.model.AnswerService”);

You only need one or the other. Either you ask WireBox to inject the AnswerService at handler creation for you with a property tag, or you retrieve it at runtime with getMode(), but you don’t need to do both. Also, you can call getModel() ANY where in the component and any time (well, except in the pseudo-constructor). There’s no need to call getModel() from onDIComplete(). You can call getModel() in your init() if you want.

Also, onDIComplete doesn’t have event, rc, and prc arguments. Only methods that represent routable actions (and their AOP helpers) have those arguments.

Furthermore, the property line asking for “answerService” will only work if Wirebox knows what “answerService” is. This can be accomplished by scan locations (which default to the root of your base models directory), or WireBox binder config mappings. Since I can’t see the rest of your code I can’t tell what other settings you have going on.

I’m a bit confused by your examples. Your first E-mail indicated that you wanted a different service based on a variable in the request collection (rc). Your sample code below shows a static service. The approach for each is a little different so I’m not sure how to help since I’m unclear on what you want.

And finally, to your specific error message you reported, “Variable CONTROLLER isundefined.” I have no clue without seeing a full trace of the error message. I think you have a lot of moving parts you’re playing with right now and it’s difficult to follow what you’ve tried.

Also, please read out getting started Reference Card for WireBox. This help explain the different injection types.
https://github.com/ColdBox/cbox-refcards/raw/master/WireBox/WireBox-Refcard.pdf

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

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

Ok. found the problem (facepalm)

`
removing init which does not call super was the problem.
function init() {

}
`

The other thing to remember is that Scott didn’t give you any advice…

But Andrew will make it clear again, the RC is defined when the request is run and is different each call and dependent on the user. So the only thing you can do is not TREAT this as a singleton and load it like your doing with getModel() if you plan on doing any DI on these models.

I think I can’t stress enough when you deal with anything, that is going to be constantly changing. That you refrain from DI’ing the objects or data into the object, as it will only be created once and create nightmares about contaminating users data and other sensitive information.

I am sure if Scott did give advice he would say the same thing.