All pages
Powered by GitBook
1 of 3

Loading...

Loading...

Loading...

Registering a Custom DSL

To register a custom namespace in WireBox, place the following configuration in the wirebox struct defined within the configure() method of your WireBox binder CFC. in a ColdBox app, this is /config/WireBox.cfc. Alternatively, you can use the mapDSL() call in the configure() method.

/config/WireBox.cfc
component extends="coldbox.system.ioc.config.Binder" {

    function configure(){
        wirebox = {
            // DSL Namespace registrations
            customDSL = {
                ortus = "path.model.dsl.MyDSL"
            }
        };

        // Or here...        
        mapDSL("ortus","path.model.dsl.MyDSL");        
    }
}

If you want to register a custom DSL namespace from a module, you can make the same call via the binder reference that is provided to your ModuleConfig.cfc.

ModuleConfig.cfc
component {
    function configure() {
        binder.mapDSL("ortus","path.model.dsl.MyDSL");
    }
}

Now I can use the ortus DSL Namespace in my mappings DSL and even my annotations, isn't that cool!

// inject it into a CFC
property name="funky" inject="ortus:funkyObject";

// map it in your WireBox Binder
map("Luis")
    .toDSL("ortus:funkyObject");

Dynamic Custom DSL Registration

Injectors allow you to register custom DSLs at runtime by using the registerDSL() method on any injector.

// Register Custom DSL
controller.getWireBox()
    .registerDSL( namespace="javaloader", path="app.model.JavaLoaderDSL" );

The DSL Builder Interface

customDSL = {
    ortus = "path.model.dsl.OrtusBuilder"
};

or
mapDSL("ortus","path.model.dsl.OrtusBuilder");

This will register a new injection DSL namespace called ortus that maps to that instantiation component path.model.dsl.OrtusBuilder. Here is a very simple DSL Builder:

<cfcomponent implements="wirebox.system.ioc.dsl.IDSLBuilder" output="false">

    <---  init --->
    <cffunction name="init" output="false" access="public" returntype="any" hint="Configure the DSL for operation and returns itself" colddoc:generic="wirebox.system.ioc.dsl.IDSLBuilder">
        <cfargument name="injector" type="any" required="true" hint="The linked WireBox injector" colddoc:generic="wirebox.system.ioc.Injector"/>
        <cfscript>
            instance = { injector = arguments.injector };
            instance.log        = instance.injector.getLogBox().getLogger( this );

            return this;
        </cfscript>
    </cffunction>

    <---  process --->
    <cffunction name="process" output="false" access="public" returntype="any" hint="Process an incoming DSL definition and produce an object with it.">
        <cfargument name="definition" required="true" hint="The injection dsl definition structure to process. Keys: name, dsl"/>
        <cfargument name="targetObject" required="false" hint="The target object we are building the DSL dependency for."/>
        <cfscript>
            var thisType             = arguments.definition.dsl;
            var thisTypeLen         = listLen(thisType,":");
            var utilName             = "";

            // DSL stages
            switch(thisTypeLen){
                // Ortus
                case 1 : { return instance.injector.getInstance('ortusUtil'); }
                // Ortus:utility
                case 2 : {
                    utilName = getToken(thisType,2,":");
                    // Verify that cache exists
                    if( instance.injector.containsInstance( 'Ortus#utilName'# ) ){
                        return instance.injector.getInstance( 'Ortus#utilName#' );
                    }
                    else if( instance.log.canDebug() ){
                        instance.log.debug("Cannot find named ortus utility #utilName# using definition: #arguments.definition.toString()#");
                    }
                    break;
                }
            } // end level 2 main DSL
        </cfscript>
    </cffunction>

</cfcomponent>

As you can see from the sample, creating your own DSL builder is fairly easy. The benefits of a custom DSL builder is that you can very easily create and extend the injection DSL language to your own benefit and if you are funky enough, override the behavior of the internal DSL Namespaces.

Custom DSL

WireBox allows you to create your own DSL object builders and then register them via your configuration binder. This allows you to create a namespace or override an internal namespace with your own object builder. By now we have seen our injection DSL and noticed that we have internal namespaces. With this feature we can alter it or create new ones so our annotations and injection DSLs can be customized to satisfaction. This is easily done in the following process

  1. Create a CFC that implements wirebox.system.ioc.dsl.IDSLBuilder

  2. Register your custom DSL builder in your configuration binder