Skip to content

Factories

The Factory concept encapsulates the "I have a object, give me a way to do X with it". This 'way' can be represented by a Class, a function or object, and is defined by the plugin point making use of the factory. What the intent of this mechanism is ( the X ), is left up to the plugin point. Examples include but are in no way limited to:

  • Finding a processor for an incoming message object
  • Presenting a React editor or view for an object
  • Exporting an XML node that represents the object
  • Finding a formatting object to convert the object to a string
  • Configuring a cache mechanism to use a different backend
  • Finding and configuring a color calculator for objects

In order to find or lookup the appropriate handling mechanism from the Factory, the object must have a type associated with it. By default, the factories look for the 'type' field on the object and use it to look up the mechanism registered in the factory.

Tip

If you are unhappy with a registered factory object (like an Editor for a Model), you can replace the install one with you own. It will be use in place of the original. Make sure your object implements all the requirements defined by the plugin point.

Creation and Registration

For a plugin point to use a Factory, it should use the createFactory( type, options, throwError = false ) method to obtain and/or create it.

const factory = Plugins.createFactory( 
  'myProject.MyLookupType',
  {
    name : 'default',
    pluginKey : 'processor',
    strategy : Plugins.ALL
  }
)

The first argument identifies the plugin point type that the Factory is using in its lookups, the second object is the options used to configure the factory:

Option Field Default Description
name default The name of the Factory. This is used to cache the factory so it can be returned from a repeated createFactory() or getFactory() call.
pluginKey plugin The key in the registered plugin that defines the item the Factory will use.
pluginKeyType type The type key name used by Factory.create() and Factory.get() when finding a factory item.
strategy Plugins.ALL This determines how to treat the item found in create() before it is returned. See below for strategy descriptions.
defaultObject null If no look up is found for a type, this object will be used
registry null The default objects in the lookup

To register a Plugins for use in the factory describe above:

const myFactoryPlugin = { 
  type : 'myObjectType',
  processor : ( obj ) => { /* do something */ }
}
Plugins.add( `myProject.MyLookupType`, myFactoryPlugin )

In this case, the type defines what kind of object this processor will be used for. Because the Factory options specified processor as the pluginKey, the actual object is registered using that key. If the factory is invoked like this

const msg = { type : 'myObjectType', /* more values */ }
const result = factory.create( msg )

the myFactoryPlugin.processor( msg ) will be invoked and its result returned. Because the stategy is ALL and the processor is a function, the function will be invoked will all parameters given to the create().

Different Strategy objects can be set on a Factory to allow different behaviors to occur. When create( obj, ...rest ) is invoked, the strategies will behave in the following ways:

Strategy Result
Plugins.ALL This is the default strategy. If the registered item is a function, it will be invoked with f( obj, ...rest ) and the result returned. If the registered item is a Class, new Clzz( obj, ...args ) will be returned.
Plugins.NONE If the registered item is a function, it will be invoked with no options. If the registered item is a Class, new Clzz( ) will be returned.
Plugins.ARGS If the registered item is a function, it will be invoked with f( ...rest ) and the result returned. If the registered item is a Class, new Clzz( ...args ) will be returned.
Plugins.MERGE If the registered item is a function, it will be invoked with f( { model : msg, ...rest } ) and the result returned. If the registered item is a Class, new Clzz( { model : msg, ...args } ) will be returned. The Plugins.mergeStrategy() call can be used to create a merge strategy that will use a different key.
Plugins.LOOKUP In this case, the registered object is simply returned
Plugins.reactStrategy( React, propKey = 'model' ) This strategy will call React.createElement() with the registered item as the component function or class. The ...rest object will be supplied as props to the component. If propKey is a string, the obj object will be given as a prop as well, using the propKey as the prop name.
function A custom function( factory, registeredItem, typeOrObject, props ) can be set as the strategy object as well.

Dynamic Factories

The Factory mechanism used in the plugin library is backed by @leverege/factory and augmented to include automatic registration and deregistration of plugins as they are added and removed.

The factory mechanism can be used independently of Plugins as well - See @leverege/factory.