Coldbox [5.6.2] Injecting into interceptor

Hi guys,

I was in 2 minds to post this because I don’t know if it would ever come up. After seeing it, I quickly realized, I didn’t actually need to “get()” anything! But it would definitely help in my understanding of the platform.

When using the postMailSend interceptor event for cbmailservices, I can’t use get() on my injected cborm entityServices.
Here is what I’ve tried:

`

property name=“ContactService” inject=“provider:Contact”;

void function postMailSend( event, interceptData, buffer, rc, prc )
{

var test = ContactService.get(5);
logger.error(‘test=’,test.getContactID());

}

`

Outcome
test= [blank]

`

property name=“ContactService” inject=“provider:entityService:Contact”;

void function postMailSend( event, interceptData, buffer, rc, prc )
{

var test = ContactService.get(5);
logger.error(‘test=’,test.getContactID());

}

`

Outcome (caught error.message)
Invalid method call: getContactID

`

property name=“ORMService” inject=“provider:entityService”;

void function postMailSend( event, interceptData, buffer, rc, prc )
{

var test = ORMService.get( entityName=“Contact”, id=5 );
logger.error(‘test=’,test.getContactID());

}

`

Outcome (caught error.message)
Invalid method call: getContactID

2 was my original method. Using it there are no problems calling ContactService.new(properties={…}) and ContactService.save(…).

Hi John,

I believe I know what the problem is.

A provider in coldbox is simply a class that implements an interface wirebox.system.ioc.IProvider. This interface requires you to implement one method called get( ).
When you inject a provider into a CFC and call a method on that provider, the class will first call the get method to instantiate the provided object (ContactService), then call the method on that object.
The whole point of this is to delay construction of the object in question until runtime. In your case you are using a virtual provider, so coldbox will automatically create a provider class and implement the get method

In your case, your are providing your ContactService which is inheriting from cborm.models.VirtualEntityService. As you know the cborm module will implement a service method called get to retrieve an entity by a specific id.

The problem is when you are calling ContactService.get(5) you are not calling the GET method on the VirtualEntityService you calling the GET method on the Provider class, which will return the ContactService.
If you dump out your test variable you should notice that it is not a a contact entity but the ContactService. Bit of a weird issue but interesting none the less.

Lucky, there is an easy fix. Dont inject your contact service. Use wirebox to get the ContactService at runtime

void function postMailSend( event, interceptData, buffer, rc, prc )
{

var ContactService = getInstance(dsl=‘entityService:Contact’);

var test = ContactService.get(5);
logger.error(‘test=’,test.getContactID());

}

Notice that i use the dsl parameter on the getInstance method

Hopefully all that makes sense

Regards
Ryan

Ryan is correct, but there’s another easier fix.

ContactService.get().get(5);

One get to get the actual instance from the provider, and a second get that is called on the actual instance. Providers use onMissingMethod to proxy method calls through, but if your actual instance has a get() method, then you can’t call it directly.

Eric Peterson and I were just talking the other day about how we should rename the get() method in providers to be something like _get() to avoid collisions. The first iteration of providers didn’t have the onmissingMethod proxy trick so method collisions wasn’t taken into account at that time.

Thanks for the explanation, Ryan.
…and…
Thanks for the fix, Brad.

I think I understand…

provider:entityService:Contact
This is saying:
wrap the provider interface around entityService which itself is wrapped around Contact

In practical terms

get().new(…)
is the same as calling
new()
because new() is actually using onMissingMethod within provider.
(I’ve just tested get().new().)

Whereas get() just gets the provider.

It makes sense. There is a lot here for me to think about regarding the fundamentals.

Thanks again - especially for the quick response.

This looks like this thread provides the explanation that I was seeking yesterday when going through the documentation samples as a new user to CB whereupon I had created this post to ask a similar question:

https://groups.google.com/forum/#!topic/coldbox/tBpj0xXKybc

Doesn’t doing this:

ContactService.get().get(5);

circumvent the caching of objects performed by Wirebox? This feels like the object gets created every time the call is made.

I also tried to create and instance to the injected provider in the init() method of my service to use later in the isloggedIn method:

property name=“SessionStorageProvider” inject=“provider:sessionStorage@cbstorages”;

securityService function init(){
variables.sessionStorage = SessionStorageProvider.get();

which is referenced in a API security Interceptor like the sample docs does it
https://coldbox.ortusbooks.com/digging-deeper/recipes/building-a-simple-basic-http-authentication-interceptor#security-service

BUT it failed with an error that the provider was not found or something.

Why don’t the docs for the authentication example show how to do this using the latest version of CB?

Hi Scott,

I am having a little trouble understanding exactly what your problem is. It seems like you have 2.

You mention that wirebox is ‘circumventing the caching of objects’, I am assuming you mean it is not persisting singleton objects in the application. If the object is not annotated as a singleton is will not be persisted (https://wirebox.ortusbooks.com/configuration/component-annotations/persistence-annotations)

The sessionStorage@cbstorages is a singleton and should be persisted regardless if you are using a provider or not. Check if you are not including ?fwreinit=1 with your request as that will clear any singletons wirebox has cached.

The other problem you mentioned that you are getting an error 'that the provider was not found or something’. Could you give the exact error output? That would be useful to debug the issue you are having.

Regards
Ryan

Hi Ryan-

Sorry for the confusion. I actually am no longer having an issue. I actually figured out on my own through debugging, dumping and trial and error how to get it working.
Then, today I saw this thread which confirmed my question on how one has to do this when injecting the provider into the service.
As a new user to CB following along with docs using the API security example I reference in my previous post, I was stumped for quite a while on why this was not working.

I am quite surprised that the docs had not been updated to show how this now done and can’t believe others have not run into the same issues, so much so that it made me wonder
what I was doing wrong.

In fact, the doc example uses this style:
property name=“sessionStorage” inject=“coldbox:plugin:SessionStorage”;

which took me a while to learn that this is no longer how it is done… That is all really on that

I provided a comprehensive reply to your cross post in your other thread you started.