Completely stumped on DI and cfproperty

Hi all,

I've read through the documentation and also other posts here
regarding DI and cfproperty and I believe I have tried just about
every configuration possible to get this to work, but I am still
having issues.

I am running CB 3.0.0 RC1 on Railo 3.2.0.003.

I have set up ModelMappings.cfm as follows:

      addModelMapping(alias='AppService',path='AppService');

I have also tried the above without the alias tag, since it's the same
as the path, and also by specifying the path as 'model.AppService'.
I've also tried no mappings at all since everything is in the model
root anyway.

For AppService.cfc, I have the cfcomponent tag set up as follows:

   <cfcomponent name="AppService" output="false">

I have also tried this with output=true and also by putting in some
cache settings.

My other model file is SiteService.cfc. The cfcomponent tag here is:

   <cfcomponent name="SiteService" output="false">

and I have this cfproperty tag:

   <cfproperty name="AppService" inject="AppService" scope="instance" /

I have also tried:

   <cfproperty name="AppService" type="model" scope="instance" />

I have also tried changing the scope to "variables".

In my SiteService.init() function I attempt to reference a method in
the AppService object as follows:

    variables.AppService.myMethodHere()

or

   instance.AppService.myMethodHere()

I've also tried putting things into an argument tag within the
SiteService.init() function, but no luck there either.

I get the same error every time:

   Error constructing model: model.SiteService
variable [APPSERVICE] doesn't existvariable [APPSERVICE] doesn't exist
at
railo.runtime.type.scope.UndefinedImpl.getCollection(UndefinedImpl.java:
404):404 at model.siteservice_cfc$cf.udfCall(/www/development/sunrise/
model/SiteService.cfc:14):14

   ... with a lot more after this

Can anyone help figure out what I am doing wrong?

Thanks,

Gary

I think its

reference it via instance.AppService.myMethodHere()

and lets not forget

i think that should do it.


Jeremy R. DeYoung
Phone: 615.261.8201

FacebookLinkedInGoogle ReaderTwitterAmazonGoogle
Google Talk/LunarFly Skype/DeYoungJD

When doing DI the rules have changed so that you don't use type="" anymore,
and you need to use inject="" instead this is very clear in the docs.

Also the app mappings the path needs the full path in dot notation.

Regards,
Andrew Scott
http://www.andyscott.id.au/

From: coldbox@googlegroups.com [mailto:coldbox@googlegroups.com] On
Behalf Of Gary
Sent: Monday, 29 November 2010 6:53 AM
To: ColdBox Platform
Subject: [coldbox:6941] Completely stumped on DI and cfproperty

Hi all,

I've read through the documentation and also other posts here regarding DI
and cfproperty and I believe I have tried just about every configuration
possible to get this to work, but I am still having issues.

I am running CB 3.0.0 RC1 on Railo 3.2.0.003.

I have set up ModelMappings.cfm as follows:

      addModelMapping(alias='AppService',path='AppService');

I have also tried the above without the alias tag, since it's the same as

the

path, and also by specifying the path as 'model.AppService'.
I've also tried no mappings at all since everything is in the model root
anyway.

For AppService.cfc, I have the cfcomponent tag set up as follows:

   <cfcomponent name="AppService" output="false">

I have also tried this with output=true and also by putting in some cache
settings.

My other model file is SiteService.cfc. The cfcomponent tag here is:

   <cfcomponent name="SiteService" output="false">

and I have this cfproperty tag:

   <cfproperty name="AppService" inject="AppService" scope="instance" /
>

I have also tried:

   <cfproperty name="AppService" type="model" scope="instance" />

I have also tried changing the scope to "variables".

In my SiteService.init() function I attempt to reference a method in the
AppService object as follows:

    variables.AppService.myMethodHere()

or

   instance.AppService.myMethodHere()

I've also tried putting things into an argument tag within the
SiteService.init() function, but no luck there either.

I get the same error every time:

   Error constructing model: model.SiteService variable [APPSERVICE]

doesn't

Hi all,

I definitely tried using the inject attribute instead of type (I saw
that in the docs) also. And I added the autowire property to
cfcomponent (didn't know about that).

But still no luck. Same error. :frowning:

<cfproperty name="AppService" inject="model:AppService" scope="instance" />
Assuming AppService is in the root of your model directory.

Curt Gratz
Computer Know How

Nope, that didn't work either.

The error I am getting now is saying that the variable INSTANCE
doesn't exist. It seems like the cfproperty tag isn't being read at
all, but I'm sure I have it configured correctly, and my mapping of
the AppService model is correct also.

I don't think that the scope is supported for WireBox, there is no mention
in the http://wiki.coldbox.org/wiki/WhatsNew:3.0.0.cfm of such a thing.

Regards,
Andrew Scott
http://www.andyscott.id.au/

From: coldbox@googlegroups.com [mailto:coldbox@googlegroups.com] On
Behalf Of Gary
Sent: Tuesday, 30 November 2010 12:10 PM
To: ColdBox Platform
Subject: [coldbox:6960] Re: Completely stumped on DI and cfproperty

Nope, that didn't work either.

The error I am getting now is saying that the variable INSTANCE doesn't

exist.

It seems like the cfproperty tag isn't being read at all, but I'm sure I

have it

Hi Andrew,

I'm not sure what that means. Do you mean that the instance scope is
not supported, or scoping in general?

I've tried the variables scope and that also hasn't worked. If scoping
isn't supported at all, how do I reference the model that's been
injected?

Thanks again,

Gary

Gary,

Either scope should still work, but the variables scope is now preferred. Can you post your config?

Curt Gratz

Hi Curt,

Thanks for the continued help. Ok, here's what I have.

My directory structure has:

model
  -- AppService.cfc
  -- SiteService.cfc

In AppService.cfc I have:

   <cfcomponent name="AppService" output="false" hint="I handle
business logic for all application settings.">
  <cffunction name="init" access="public" output="false"
hint="Constructor">
    <cfreturn this>
  </cffunction>

       <cffunction name="getStagingURL" access="public" output="false"
hint="I return the URL of the staging server as defined in config
settings.">
    <cfset var stagingURL = "testing.emergingsky.com">
    <cfreturn stagingURL>
  </cffunction>
   </cfcomponent>

In SiteService.cfc I have:

   <cfcomponent name="SiteService" output="false" hint="I handle
business logic for all site settings.">
  <cfproperty name="AppService" inject="model">

        <cffunction name="init" access="public" output="false"
hint="Constructor">
    <cfset var app = variables.AppService.init()>
    <cfset var stagingURL = app.getStagingURL()>
          [other unimportant code]
        </cffunction>
   </cfcomponent>

When I run all this, I get this error:

Error constructing model: SiteService
Component [model.SiteService] has no acessible Member with name
[APPSERVICE]Component [model.SiteService] has no acessible Member with
name [APPSERVICE]

Now, I have also tried removing the <cfproperty> tag and instead
injecting the model via cfargument. When I do this, I insert this code
into the SiteService.cfc init method:
     <cfargument name="AppService" type="any" inject="model">

When I do this, I get a different error. It says that it cannot
perform the init() method because the object is empty.

Let me know if I can provide anything else. Thanks!

Gary

Gary,

Since you are needing this for your constructor of the siteservice, you will need to use the arguments inject annotation. Redo your siteservice to look like below.

   <cfcomponent name="SiteService" output="false" hint="I handle business logic for all site settings.">

        <cffunction name="init" access="public" output="false" hint="Constructor">
          <cfargument name="AppService" type="any" inject="model" />
      <cfset var app = arguments.AppService>
      <cfset var stagingURL = app.getStagingURL()>
        </cffunction>
   </cfcomponent>

And you should be good to go.

Hope that helps,
Curt Gratz
Computer Know How

Hi Curt,

I did what you suggested. I am now getting this:

     variable [APP] doesn't exist

As always, thanks for your help!

Gary

Hi Curt,

I did what you suggested. I am now getting this:

     variable [APP] doesn't exist

As always, thanks for your help!

Gary

Gary,

Do you have the autowire interceptor enabled in your config.

//Register interceptors as an array, we need order
    interceptors = [
      //Autowire
      {class="coldbox.system.interceptors.Autowire",
       properties={ }
      } ];

Hi Curt,

Yes, here's what I have:

<Interceptors>
   <!-- USE AUTOWIRING -->
   <Interceptor class="coldbox.system.interceptors.Autowire" />
   <!-- USE SES -->
   <Interceptor class="coldbox.system.interceptors.SES">
      <Property name="configFile">config/routes.cfm</Property>
      <Property name="LooseMatching">true</Property>
   </Interceptor>
</Interceptors>

Gary, it is referenced like this

Property name='nameofInjection' inject;

And called like this

Nameofinjection.methodtoCall();

Regards,
Andrew Scott
http://www.andyscott.id.au/

From: coldbox@googlegroups.com [mailto:coldbox@googlegroups.com] On
Behalf Of Gary
Sent: Wednesday, 1 December 2010 1:36 AM
To: ColdBox Platform
Subject: [coldbox:6980] Re: Completely stumped on DI and cfproperty

Hi Andrew,

I'm not sure what that means. Do you mean that the instance scope is not
supported, or scoping in general?

I've tried the variables scope and that also hasn't worked. If scoping

isn't

Gary have you read this

http://wiki.coldbox.org/wiki/WhatsNew:3.0.0.cfm

Your injection is wrong and it is explained in this link how to make the
call.

You can use inject on its own, but as soon as you put a type you need to
specify the name as well.

So this

<cfproperty name="AppService" inject="model">

Becomes

<cfproperty name="AppService" inject="model: AppService">

But you should read this http://wiki.coldbox.org/wiki/WhatsNew:3.0.0.cfm

Regards,
Andrew Scott
http://www.andyscott.id.au/

From: coldbox@googlegroups.com [mailto:coldbox@googlegroups.com] On
Behalf Of Gary
Sent: Wednesday, 1 December 2010 2:30 AM
To: ColdBox Platform
Subject: [coldbox:6984] Re: Completely stumped on DI and cfproperty

Hi Curt,

Thanks for the continued help. Ok, here's what I have.

My directory structure has:

model
  -- AppService.cfc
  -- SiteService.cfc

In AppService.cfc I have:

   <cfcomponent name="AppService" output="false" hint="I handle business
logic for all application settings.">
  <cffunction name="init" access="public" output="false"
hint="Constructor">
    <cfreturn this>
  </cffunction>

       <cffunction name="getStagingURL" access="public" output="false"
hint="I return the URL of the staging server as defined in config

settings.">

    <cfset var stagingURL = "testing.emergingsky.com">
    <cfreturn stagingURL>
  </cffunction>
   </cfcomponent>

In SiteService.cfc I have:

   <cfcomponent name="SiteService" output="false" hint="I handle business
logic for all site settings.">
  <cfproperty name="AppService" inject="model">

        <cffunction name="init" access="public" output="false"
hint="Constructor">
    <cfset var app = variables.AppService.init()>
    <cfset var stagingURL = app.getStagingURL()>
          [other unimportant code]
        </cffunction>
   </cfcomponent>

When I run all this, I get this error:

Error constructing model: SiteService
Component [model.SiteService] has no acessible Member with name
[APPSERVICE]Component [model.SiteService] has no acessible Member with
name [APPSERVICE]

Now, I have also tried removing the <cfproperty> tag and instead injecting
the model via cfargument. When I do this, I insert this code into the
SiteService.cfc init method:
     <cfargument name="AppService" type="any" inject="model">

When I do this, I get a different error. It says that it cannot perform

the init()

method because the object is empty.

Let me know if I can provide anything else. Thanks!

Gary

> Gary,
>
> Either scope should still work, but the variables scope is now
preferred. Can you post your config?
>
> Curt Gratz
>
> From: coldbox@googlegroups.com [mailto:coldbox@googlegroups.com]
On
> Behalf Of Gary
> Sent: Tuesday, November 30, 2010 8:36 AM
> To: ColdBox Platform
> Subject: [coldbox:6980] Re: Completely stumped on DI and cfproperty
>
> Hi Andrew,
>
> I'm not sure what that means. Do you mean that the instance scope is not
supported, or scoping in general?
>
> I've tried the variables scope and that also hasn't worked. If scoping

isn't

Andy,

Thanks very much, but I have tried this before (and just tried again)
and this doesn't work. I read the What's New documentation and I see
(and think I understand) how the injection is supposed to be coded,
but it doesn't seem to be working. I have tried all kinds of
variations on the cfproperty tag, including inject="model" and
inject="model:AppService" and have gotten nowhere with either.

Also, according to Curt, I can't use cfproperty if I am attempting to
inject within an init function. I'm told I have to use cfargument
instead. And I have tried all kinds of variations on that.

I'm sure that the fault is somewhere in my code but I can't figure out
what it is. I feel like I've done everything the way I should, and
even tried all kinds of variations.

Maybe there's something I am missing in the documentation. I will keep
trying, and I welcome any more suggestions anyone has.

Ok I came across this a few weeks ago, you need to look into the DIComplete
option of the config settings.

Regards,
Andrew Scott
http://www.andyscott.id.au/

From: coldbox@googlegroups.com [mailto:coldbox@googlegroups.com] On
Behalf Of Gary
Sent: Wednesday, 1 December 2010 8:11 AM
To: ColdBox Platform
Subject: [coldbox:7003] Re: Completely stumped on DI and cfproperty

Andy,

Thanks very much, but I have tried this before (and just tried again) and

this

doesn't work. I read the What's New documentation and I see (and think I
understand) how the injection is supposed to be coded, but it doesn't seem
to be working. I have tried all kinds of variations on the cfproperty tag,
including inject="model" and inject="model:AppService" and have gotten
nowhere with either.

Also, according to Curt, I can't use cfproperty if I am attempting to

inject

within an init function. I'm told I have to use cfargument instead. And I

have

tried all kinds of variations on that.

I'm sure that the fault is somewhere in my code but I can't figure out

what it

is. I feel like I've done everything the way I should, and even tried all

kinds of

I have never used ColdBox's built-in DI.

Based upon my experience with writing my own IoC/DI framework and using others (namely ColdSpring), I am going to guess that Curt had you most of the way there.

You definitely cannot call on an injected component within init(), as the init() method is run prior to DI. So using arguments to pass the necessary object(s) is the correct way to go. I believe the one missing ingredient is this:

That would set the AppService to a local variable within the init() method, which would not be available thereafter. So, I believe you will need to change that to:

Having done that, you should be able to safely call variables.app anywhere else within the CFC.

HTH