Auto-wiring - Mura Docs v6

Auto-wiring

Mura uses auto-wiring to speed plugin development.

Auto-wiring is a mechanism that links objects by convention, in this case by the name of the object being present in the Session and / or Application scope. This makes it easy to manage objects and relationships without having to physically link and/or create them throughout our application.

Session and Application Object Auto-Wiring

Mura's Session and Application object offer simple dependency auto-wiring. If you are familiar with ColdSpring dependency framework, you will be familiar with how this works.

When pulling an value from the object Mura looks for defined methods matching the set{key} format and then simply looks to see if {key} also exists in the object. If it does, Mura fires {object}.set{key}({key}). Mura will also look into the main Mura service factory for key values that are not found locally.

Let's look at how we would use this in a plugin. First, we create a couple of objects that contains some functions that will be reused throughout our plugin:

/cfc/Library.cfc

component extends="mura.cfobject"{
variables.dateManager = "";
public library function init(){
return this;
}
public any function getRandomValue() {
return randRange(1,100);
}
public any function setDateManager(dateManager) {
variables.dateManager = arguments.dateManager;
}
public any function getDateManager" output="false" {
return variables.dateManager;
}
public any function setPluginConfig(pluginConfig) {
variables.pluginConfig = arguments.PluginConfig;
}
public any function getPluginConfig" output="false" {
return variables.pluginConfig;
}
}

/cfc/DateManager.cfc

component extends="mura.cfobject"{
variables.library = "";
public dateManager function init(){
return this;
}
public any function getDate() {
return now();
}
public any function setLibrary(library) {
variables.library=arguments.library;
}
public any function getLibrary" output="false" {
return variables.library;
}
}

Next, we add these objects to our application scope:

/index.cfm

<cfscript>
include "/plugin/config.cfm";
var pApp = variables.pluginConfig.getApplication();
var myLibrary = CreateObject('myLibrary', 'cfcs.library');
var myDateManager = CreateObject('dateManager', 'cfcs.dateManager');
pApp.setValue('library', myLibrary);
pApp.setValue('dateManager', myDateManager);
</cfscript>

After adding these objects to the PluginConfig's Application scope, Mura will 'wire' them together because of the set{object}() and get{object}() functions. When Mura sees set{object}(), and an object with the {object} name exists in the Application scope, Mura calls the set{object}() function and assigns that object. You can also do this in an onApplicationStart() eventHandler event:

/events/eventHandler.cfc

component extend="mura.plugin.pluginGenericEventHandler" {
public any function onApplicationLoad($) {
var myLibrary = CreateObject('myLibrary', 'cfcs.library');
var myDateManager = CreateObject('dateManager', 'cfcs.dateManager');
var pApp = variables.pluginConfig.getApplication();
pApp.setValue('library', myLibrary);
pApp.setValue('dateManager', myDateManager);
}
public any function onMyCustomEvent($){
var pApp = variables.pluginConfig.getApplication();
var myLibrary = pApp.getValue('library');
/*
The dateManager was never explicitly set or created;
instead, we have accessed it via auto-wiring
*/
var myDateManager = library.getDateManager();
/*
The pluginConfig is also never explicitly set. But since the plugin
application object knows what plugin is belongs to it can automatically
set it as well
*/
var pluginConfig = library.getPluginConfig();
}
}

EventHandler Auto-Wiring

A different type of auto-wiring occurs within events. As we've seen in previous examples within Mura, we are able to register all functions within an object as event listeners simply by registering the object itself.

The way we do this is by using the pluginConfig.addEventHandler({component}) function. This function, designed to be used within a registered onApplicationLoad() event, will auto-wire an entire component's methods by naming convention.

/events/eventHandler.cfc

component extends="mura.plugin.pluginGenericEventHandler"{
public any function onApplicationLoad($){
variables.pluginConfig.addEventHandler(this);
}
public any function onCustomEvent($){
//do custom stuff
}
public any function onAnotherCustomEvent($){
//do custom stuff
}
}

You may recall from previously that Mura CMS events follow a specific pattern in their naming conventions:

  • standard{event}
  • on{event}
  • onGlobal{event} --onGlobal events are NOT site bound

Any functions in the eventHandler that follow this naming convention will subsequently be registered as event listeners. Remember that you must register the object's onApplicationLoad() function within the plugin's config.xml.