AMW - Another Module Wiring
Smart module wiring using dependency injection container
This library can be used as a framework for your modern java script projects.
Installation
npm install amw
Importing
// Using Node.js `require()`const Wire = ;
Overview
Define dependencies
First, we need to define the dependencies we want in our app. create a file di.js
and here is our
dependencies for the app.
// di.jsconst message = { if configpre_message return ` ` return ``} { return num1 + num2 } { return num1 - num2 } moduleexports = 'message': 'mathOps': 'main': { const result = mathOps return } tags: 'main'
each dependency should have a unique name, here we have 3 dependencies message
, mathOps
and main
.
each dependency shall have the following attributes
1- factory
:
a factory function that should return a function
or an object instance
, and this way we can ensure
only single instance per application for each dependency.
the factory arguments can be our defined services like the case of the main factory function as it
expects both mathOps
and message
services as arguments.
there is another argument that we can access which is the config
argument, and that is the configuration
exported by our config.js
file. check the Define Config section.
2- tags
:
an array of tags, we can use to group services under the same tag for fast access, the main
tag is
reserved for the main service only.
Define Config
The config file is where we can keep our configuration for all our services in the same place. in this file we need to export an object of service configuration.
// config.jsmoduleexports = message: pre_message: 'result is:'
here we just have configuration for the message service, and we use it in the message factory function.
Wiring services
Next we need to wire all those services and start our application, we shall do that in main.js
file
// main.jsconst Wire = ;const DI_FILE_LOCATION = ''; // location of di.js fileconst CONFIG_FILE_LOCATION = ''; // location of config.js file // define new wire instanceconst wireInstance = DI_FILE_LOCATION CONFIG_FILE_LOCATION // connect dependencies defined in di.jsconst container = wire // get the main serviceconst main = container // call the main function
next run
$ node main.js// result is: 6
the connect
function returns a container
object that we used to get the main service and call it.
the container
has other useful functions.
Container
The container contains all services defined in di.js
, and it is used internally to register the services
defined when we called wire.connect()
, but it can also be used externally for service registration.
Methods
container.register(name, service)
Register new service
Kind: instance method of Container
Param | Type | Description |
---|---|---|
name | string |
Service name. |
service | number |
Service object |
service.dependency | * |
Whatever you want. |
service.factory | function |
factory function |
[service.tags] | Array.<string> |
tags array |
Example
// register dependencycontainer
Example
// register factory with tagcontainer
*
container.getService(name) ⇒ Get service by name
Kind: instance method of Container
Returns: *
- service - Registered service
Param | Type | Description |
---|---|---|
name | string |
Service name. |
Example
// get dependencyconst secret = container// secret = 'some-secret'
Example
// get factoryconst logger = container// secret is: some-secret
*
container.getMainService() ⇒ Get main service
Kind: instance method of Container
Returns: *
- service - Registered service with tag 'main'
*
container.getTaggedServices(tag) ⇒ Get services by tag
Kind: instance method of Container
Returns: *
- services - array of services
Param | Type | Description |
---|---|---|
tag | string |
Service tag. |
More info
If you are interested to learn more cool design patterns in node.js I recommend this book Node.js Design Patterns by Mario Casciaro and Luciano Mammino.