Wire: Invoking factory functions in multiple-factory modules

23 views
Skip to first unread message

Bill W

unread,
Dec 10, 2014, 3:10:17 PM12/10/14
to cuj...@googlegroups.com
I just got started with wire and am investigating how we will use it in our node.js applications.  I'm not seeing a straightforward way to use factory functions when multiple are bundled into a single module, as I've often seen with node.js modules.  I can think of a couple ways of doing it, but I wanted to find out if there was a better way or if there are features I just haven't run across (since I'm only days into working with wire).

First the case that works nicely:

Say I want to use a module "singlefactory.js" that looks like:

module.exports = function makeSomething(a,b,c) {
 
var objectBeingBuilt;
 
// ... build object using arguments ...
 
return objectBeingBuilt;
};

I can easily use the factory with parameters with a spec like:

{
  mySomething
: {
    create
: {
     
module: 'singlefactory',
      args
: [11, 22, 33]
   
}
 
}
}


Now suppose instead I have a module with multiple factory functions (call it "multifactory.js") like this:

module.exports = {
  makeSomething
: function(a,b,c) {
   
return { /* ... */ };
 
},
  make
SomethingElse: function(a,b,c,d) {
    return { /* ... */ };
 
},
 
// ... etc ...
};

I don't see any syntax that would let me do this in a spec:

{
  myThis: {
    create: {
      module: 'multifactory.make
Something',    // not valid
      args: [11, 22, 33]
    }
  }
}

The following works, but doesn't let me pass arguments:

{
  multifactoryModule: {
    module: 'multifactory'
  },

  myThis: {
    create: {$ref: '
multifactoryModule.makeSomething'}  // calls makeSomething, but with no args
  }
}

I know that the preferred module structure is to have each module contain a single factory (or class or object) as was discussed in this thread here: https://groups.google.com/forum/#!topic/cujojs/j7pSiNDnSRU, but the modules I'm using were not written that way.

The two solutions I thought of were:

A.  Write a wrapper module for each factory function I want to use, like:

multifactoryModule').

which gets rather tedious and yields a lot of tiny files.

B.  Write my own custom factory.  I could make a takeoff of create that allows both a ref and an arg list.  Having looked at the implementation of the instanceFactory (the factory behind "create") in basePlugin.js, it would be easy enough to do.  Just something about doing that seemed a little dirty, and in any case I don't want to be writing customizations if there are features already in wire that would do this directly "out of the box".


So are there other ways of accomplishing this?

Brian Cavalier

unread,
Dec 22, 2014, 4:11:50 PM12/22/14
to cuj...@googlegroups.com
Hey Bill,

You should be able to use node's require() directly in a wire spec.  For example, try the following:

{
  myThis
: {
    create
: {
     
module: require('multifactory').makeSomething,
      args
: [11, 22, 33]
   
}
 
}
}



Wire will see that `module` is set to an actual function and will use it directly.  Let me know if you have any trouble with that.

b

Bill W

unread,
Jan 15, 2015, 11:26:52 AM1/15/15
to cuj...@googlegroups.com
That worked for me.

Just as a side note, this works since I am defining my specs in a require()'d .js file.  If I were loading them from JSON (e.g. read the file and JSON.parse()), then this wouldn't be an option.

Thanks!

Brian Cavalier

unread,
Jan 15, 2015, 2:20:08 PM1/15/15
to cuj...@googlegroups.com
Great, glad that worked.

It's true, wire specs written as actual JS modules, rather than as JSON, have much more flexibility.  In general, I recommend going that route whenever possible.

Cheers,
b
Reply all
Reply to author
Forward
0 new messages