How can I make a WireBox injected dependency available to a constructor method?

Dave L

In this example, I have a model object called test.cfc which has a dependency testService.cfc.

test has WireBox inject testService through a property declaration. The object looks like this:

component {

     property name="testService" inject="testService";

     /**
     *  Constructor
     */
     function init() {

         // do something in the test service
         testService.doSomething();

         return this;

     }

 }

For reference, testService has a single method called doSomething() which dumps out some text:

component
     singleton
{

     /**
     *  Constructor
     */
     function init() {

         return this;

     }


     /**
     *  Do Something
     */
     function doSomething() {

         writeDump( "something" );

     }

 }

The problem is, WireBox doesn't seem to inject testService until after the constructor init() method fires. So, if I run this in my handler:

prc.test = wirebox.getInstance(
     name = "test"
);

I get the following error message: Error building: test -> Variable TESTSERVICE is undefined.. DSL: , Path: models.test

Just for sanity sake, if I modify test so that testService gets referenced after the object is constructed, everything works fine. The problem seems to be isolated to constructor methods.

How can I make sure my dependencies can be referenced in my object constructor methods? Thanks for your assistance!

Brad Wood

Due to the order of construction, you can't use property or setter injections in the init() method. Instead, you can access them in the onDIComplete() method. I realized the WireBox docs only had a passing reference to this, so I have added this excerpt:

https://wirebox.ortusbooks.com/usage/injection-dsl/id-model-empty-namespace#cfc-instantiation-order

CFC Building happens in this order.

  1. Component is instantiated with createObject()
  2. CF automatically runs the pseudo constructor (any code outside the a method declaration)
  3. The init() method is called (if it exists), passing any constructor args
  4. Property (mixin) and setting injection happens
  5. The onDIComplete() method is called (if it exists)

So the proper version of your CFC would be as follows:

component {

     property name="testService" inject="testService";

     /**
     *  Constructor
     */
     function init() {
         return this;
     }

     /**
     *  Called after property and setter injections are processed
     */
     function onDIComplete() {
         // do something in the test service
         testService.doSomething();
     }

 }

Note, it would also be acceptable to switch to constructor injection, but my personal preference is property injection due to the reduced boilerplate of needing to receive the argument and persist it locally.

https://wirebox.ortusbooks.com/usage/wirebox-injector/injection-idioms

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How can i make a method available only from within the class

How to register a class with a dependency injected constructor? (SimpleIoC)

How can I make a VS Code reference from one class to another class file while it is injected through a constructor?

How can I make a list defined in one method available in another method when both methods are in the same class?

How do I make a constructor available to only the factory class?

How I can make my constructor synchronized?

How can I make a variable in the constructor make it optional (flutter)?

How to call a method service injected in another constructor service PHP Symfony

How to make constructor or setter based dependency injection?

can I reduce dependency injection on constructor

How can I make a pattern rule dependency optional in a Makefile?

How can I make a non-assisted dependency assisted?

How can I make a condition to check an appointment if it is available or not in php?

How can I make webpack externals available to jest

How can I make my webserver running on android publically available

How can I make a way to return error message of record not available?

How can I make new fields available to the report designer?

How can I make my textfield fill the available vertical space?

How can I make the goaccess package available in Lucid (10.04)?

How can I make collection available to all views in Laravel?

How can I make macOS frameworks available to clang in a Nix environment?

How can I make a value modified in a child component available to the parent?

How can I make the LLVM IR of a function available to my program?

How can I make environment variables available during Vagrant provisioning?

How can I make functions available to ClojureScript's eval?

How can I make Rasdial execute again if a connection is not yet available?

How can I make the entity field type available in silex?

How can i make only one choice available from 3?

How can I trigger a method after a variable in a dependency is updated?

TOP Ranking

HotTag

Archive