# Module Definition

A module must be a folder that contains following files:

* `meta.js`(required) a.k.a module's header, provides metadata of the module.
* `index.js`(optional) a.k.a module's body, encapsulates module execution code.

## Module Metadata

Metadata is mandatory for all modules. It must be an object that is assigned to`module.exports`and may have following properties:

* `use`(optional): An array that specifies dependencies which will be passed to this module via Constructor or a Building Method.
* `set`(optional): An object that specifies dependencies which will be injected to module via Property Injection.
* `singleton`(optional): A flag that indicates if the module instance is singleton or not. False (transient) by default.
* `install`(optional): A method that is used for custom installation of the module. See [Customizing Module Installation](#customizing-module-installation) for more information.
* `on`(optional): An object that contains a Pre-installation Check, a Post-installation Check and a Final Check functions. See [Module Installation Checks](#module-installation-checks) for more information.

For example, given your application has four custom modules:`users`,`log`,`emitter`, and`db`. All located in folder`modules`:

```
app
|- index.js
|- modules
|  |- users
|  |  |- meta.js
|  |  |- index.js
|  |- db
|  |  |- meta.js
|  |  |- index.js
|  |- log
|  |  |- meta.js
|  |  |- index.js
|  |- emitter
|  |  |- meta.js
|  |  |- index.js
```

In which,`users`uses`db`to save a certain user to database, and uses`log`to log errors occurring in update operation. It also uses`emitter`to emit a`user-updated`event when the given user got updated.

```javascript
// users/index.js
module.exports = (db, log) => new (function(db, log) {
    this.emitter = undefined;

    this.updateUser = function(user) {
        var emitter = this.emitter;
        db.update(user)
            .then(user => {
                emitter.emit('user-updated', user);
            })
            .catch(ex => {
                log.error(ex);
            });
    }

})(db, log);
```

So the metadata of the module`users`may look like:

```javascript
// users/meta.js
module.exports = {
    use: ['db', 'log'], // both db and log will be passed to module constructor.
    set: { emitter: 'emitter' } // emitter will be injected via property injection, after module is created.
    singleton: true // false if not specified.
}
```

## Module Payload

Module payload contains module body that is assigned to`module.exports`. The body can be one of following: An Object, A Method, or A Class.

A module may or may not have payload. When a module only has metadata, it becomes Thin Module (see Thin Module for more information).

### An Object

The module will be treated as an instance and will be installed to the container via Instance Binding.

```javascript
// index.js
module.exports = {
    error: function(ex) {
        console.log(ex);
    }
}
```

### A Method

The module will be treated as a method that returns instance of the module later on, and will be installed to the container via Method Binding.

```javascript
// index.js
class Logger() {
    constructor (strategy) {
        this.strategy = strategy;
    }

    error(ex) {
        this.strategy.error(ex);
    }
}

module.exports = (active) => new Logger(active);
```

### A Class

The module will be treated as a class and will be installed to the container via Class Binding.

```javascript
// index.js
class Logger() {
    constructor (strategy) {
        this.strategy = strategy;
    }

    error(ex) {
        this.strategy.error(ex);
    }
}

module.exports = Logger;
```
