Providers
This directory contains providers contributing additional bindings, for example
custom sequence actions.
Overview
A provider
is a class that provides a value()
function. This function is called Context
when another entity requests a value to be injected.
Here we create a provider for a logging function that can be used as a new
action in a custom sequence.
The logger will log the URL, the parsed request parameters, and the result. The
logger is also capable of timing the sequence if you start a timer at the start
of the sequence using this.logger.startTimer()
.
Basic Usage
TimerProvider
TimerProvider is automatically bound to your Application's
Context using the LogComponent
which exports this provider with a binding key of extension-starter.timer
. You
can learn more about components in the
related resources section.
This provider makes availble to your application a timer function which given a
start time (given as an array [seconds, nanoseconds]) can give you a total
time elapsed since the start in milliseconds. The timer can also start timing if
no start time is given. This is used by LogComponent to allow a user to time a
Sequence.
NOTE: You can get the start time in the required format by using
this.logger.startTimer()
.
You can provide your own implementation of the elapsed time function by binding
it to the binding key (accessible via ExtensionStarterBindings
) as follows:
app.bind(ExtensionStarterBindings.TIMER).to(timerFn);
LogProvider
LogProvider can automatically be bound to your Application's Context using the
LogComponent which exports the provider with a binding key of
extension-starter.actions.log
.
The key can be accessed by importing ExtensionStarterBindings
as follows:
Example: Binding Keys
import {ExtensionStarterBindings} from 'HelloExtensions';
const key = ExtensionStarterBindings.LOG_ACTION;
LogProvider gives us a seuqence action and a startTimer
function. In order to
use the sequence action, you must define your own sequence as shown below.
Example: Sequence
class LogSequence implements SequenceHandler {
constructor(
@inject(coreSequenceActions.FIND_ROUTE) protected findRoute: FindRoute,
@inject(coreSequenceActions.PARSE_PARAMS)
protected parseParams: ParseParams,
@inject(coreSequenceActions.INVOKE_METHOD) protected invoke: InvokeMethod,
@inject(coreSequenceActions.SEND) protected send: Send,
@inject(coreSequenceActions.REJECT) protected reject: Reject,
@inject(ExtensionStarterBindings.LOG_ACTION) protected logger: LogFn,
) {}
async handle(context: RequestContext) {
const {request, response} = context;
let args: any = [];
let result: any;
const start = this.logger.startTimer();
try {
const route = this.findRoute(request);
args = await this.parseParams(request, route);
result = await this.invoke(route, args);
this.send(response, result);
} catch (error) {
result = error;
this.reject(context, error);
}
this.logger(request, args, result, start);
}
}
Once a sequence has been written, we can just use that in our Application as
follows:
Example: Application
const app = new Application({
sequence: LogSequence,
});
app.component(LogComponent);
Related Resources
You can check out the following resource to learn more about providers,
components, sequences, and binding keys.