Adding a new service
Summary
You can take advantage of the pluggable architecture of this library by choosing different implementations for services, and/or adding new service roles altogether. A service is just a Javascript class that inherits from either PublicService
, PrivateService
, or LocalService
, and contains public method(s).
It can depend on other services through our built-in dependency injection framework, and can also be configured through the Maker config file / config options.
Steps to add a new service
The information below is written for developers who want to add to dai.js, but you can also add services through the use of plugins.
Here are the steps to add a new service called ExampleService:
(1) In the src directory, create an ExampleService.js file in one of the subdirectories.
(2) In src/config/DefaultServiceProvider.js, import ExampleService.js and add it to the _services array
(3) Create a class called ExampleService in ExampleService.js
(4) The service must extend one of:
PrivateService - requires both a network connection and authentication
PublicService - requires just a network connection
LocalService - requires neither
See the Service Lifecycle section below for more info
(5) In the constructor, call the parent class's constructor with the following arguments:
The name of the service. This is how the service can be referenced by other services
An array of the names of services to depend on
(6) Add the necessary public methods
(7) If your service will be used to replace a default service (the full list of default service roles can be found in src/config/ConfigFactory), then skip this step. Otherwise, you'll need to add your new service role (e.g. "example") to the ServiceRoles array in src/config/ConfigFactory.
(8) Create a corresponding ExampleService.spec.js file in the test directory. Write a test in the test file that creates a Maker object using your service.
(9) (Optional) Implement the relevant service lifecycle functions (initialize(), connect(), and authenticate()). See the Service Lifecycle section below for more info
(10) (Optional) Allow for configuration. Service-specific settings can be passed into a service by the Maker config file or config options. These service-specific settings can then be accessed from inside a service as the parameter passed into the initialize function (see the Service Lifecycle section below)
Service Lifecycle
The three kinds of services mentioned in step 4 above follow the following state machine diagrams in the picture below.
To specify what initializing, connecting and authenticating entails, implement the initialize(), connect(), and authenticate() functions in the service itself. This will be called while the service's manager brings the service to the corresponding state.
A service will not finish initializing/connecting/authenticating until all of its dependent services have completed the same state (if applicable - for example a LocalService is considered authenticated/connected in addition to initialized, if it has finished initializing). The example code here shows how to wait for the service to be in a certain state.
Adding Custom Events
One way to add an event is to “register” a function that gets called on each new block, using the event service's registerPollEvents() function. For example, here is some code from the price service. this.getEthPrice() will be called on each new block, and if the state has changed from the last call, a price/ETH_USD event will be emitted with the payload { price: [new_price] }.
Another way to an add an event is to manually emit an event using the event service's emit function. For example, when the Web3Service initializes, it emits an event that contains info about the provider.
Note that calling registerPollEvents and emit() directly on the event service like in the previous two examples will register events on the "default" event emitter instance. However, you can create a new event emitter instance for your new service. For example, the CDP object defines it's own event emitter, as can be seen here, by calling the event service's buildEmitter() function.
Last updated