WireBox is a great way to handle dependency injection through inversion of control. Dependencies are injected precisely where you need it.
16 december 2020
There are many ways to use WireBox, but in this blog we will focus on one: injection using component properties. Property injection is a great self-documenting way to specify dependencies right there in your objects.
With implementing WireBox, all the occurrences of CreateObject or cfinvoke in your code will be replaced by calling WireBox for the same object. WireBox tries to find that object based on the binder configuration. All is done using aliases which are derived from the CFC file name.
The goal of this blog is not to explain what WireBox is and how it works in detail, but to implement it successfully into your legacy application as fast as possible and go from there. Making the dependencies manageable will help modernize your application and start using TestBox and MockBox for instance, or even migrate to ColdBox.
WireBox can be installed in multiple ways. Because we are focussed on a stand-alone setup (no other Box products used) we will describe the manual installation.
Download WireBox from (open Wirebox category):
Extract the ZIP file into the wirebox folder of your project, so you create /wirebox.
To start using WireBox in your application, add the following to the OnApplicationStart function inside your Application.cfc file:
<cfset application.wirebox = createObject("component","wirebox.system.ioc.Injector").init() />
To tell WireBox which components you have, the easiest way is to let him figure it out by scanning the folder that contains your CFC’s. In the following example that is the /com folder.
Add the following code to your Application.cfc onApplicationStart function:
<!--- Get our binder ---> <cfset local.binder = application.wirebox.getBinder() /> <!--- map all CFC's in the /com folder ---> <cfset local.binder.mapDirectory("com").noInit().asSingleton() />
The method .asSingleton() makes sure we only have one copy of that component in WireBox. The default is to create a new version every time we need it, and that’s not what we want.
The method .noInit() disables the initialization of the component so that we don’t have issues with circular references, this is the most powerful feature of Wirebox.
More information for setting up the binder can be found on https://wirebox.ortusbooks.com/content/mapping_dsl/persistence_dsl.html.
In the component you can define the dependencies by specifying a property (https://wirebox.ortusbooks.com/content/wirebox_injector/injection_idioms.html) with the name of the alias. Properties for a component are defined just below the cfcomponent tag above the functions:
<cfproperty name="settings" inject="settings" scope="this" />
In this example the property name is the same as the alias for your component and this will be injected into the this.settings variable to use. So if you have a function named getSettings() inside the settings component, you can call it with the following code:
<cfset variables.allSettings = this.settings.getSettings() />
So every dependent component can be used by their name in this scope. Modify all the createObject and cfinvoke tags to use this new way of calling the function in the dependent components.
Another way to use WireBox is by simply calling the component using the WireBox function getInstance() like this:
<cfset variables.allSettings = application.wirebox.getInstance.(‘settings’).getSettings() />
Check out the links below to read more interesting blogs and articles.