Services Manager
Overview​
Services manager is the single point of service registration. Each service needs
to implement a create
method which gets called inside ServicesManager
to
instantiate the service. In the app, you can get access to a registered service
via the services
property of the ServicesManager
.
Skeleton​
Simplified skeleton of ServicesManager
is shown below. There are two public
methods:
registerService
: registering a new service with/without a configurationregisterServices
: registering batch of services
export default class ServicesManager {
constructor(commandsManager) {
this._commandsManager = commandsManager;
this.services = {};
this.registeredServiceNames = [];
}
registerService(service, configuration = {}) {
/** validation checks **/
this.services[service.name] = service.create({
configuration,
commandsManager: this._commandsManager,
});
/* Track service registration */
this.registeredServiceNames.push(service.name);
}
registerServices(services) {
/** ... **/
}
}
Default Registered Services​
By default, OHIF-v3
registers the following services in the appInit
.
servicesManager.registerServices([
CustomizationService,
UINotificationService,
UIModalService,
UIDialogService,
UIViewportDialogService,
MeasurementService,
DisplaySetService,
ToolBarService,
ViewportGridService,
HangingProtocolService,
CineService,
]);
Service Architecture​
If you take a look at the folder of each service implementation above, you will
find out that services need to be exported as an object with name
and create
method.
For instance, ToolBarService
is exported as:
import ToolBarService from './ToolBarService';
export default {
name: 'ToolBarService',
create: ({ configuration = {}, commandsManager }) => {
return new ToolBarService(commandsManager);
},
};
and the implementation of ToolBarService
lies in the same folder at
./ToolbarSerivce.js
.
Note: The create method is critical for any custom service that you write and want to add to the list of services
Note: For typescript definitions, the service type should be exported as part of the Types export on the module. This is recommended going forward and existing services will be migrated. As well, the capitalization of the name should be lower camel case, with the type being upper camel case. In the above example, the service instance should be
toolBarService
with the class beingToolBarService
.
Accessing Services​
Throughout the app you can use services
property of the service manager to
access the desired service.
For instance in the PanelMeasurementTableTracking
which is the right panel in
the longitudinal
mode, we have the simplified code below for downloading the
drawn measurements.
function PanelMeasurementTableTracking({ servicesManager }) {
const { MeasurementService } = servicesManager.services;
/** ... **/
async function exportReport() {
const measurements = MeasurementService.getMeasurements();
/** ... **/
downloadCSVReport(measurements, MeasurementService);
}
/** ... **/
return <> /** ... **/ </>;
}
Registering Custom Services​
You might need to write you own custom service in an extension.
preRegistration
hook inside your extension is the place for registering your
custom service.
import WrappedBackEndService from './services/backEndService';
export default {
// ID of the extension
id: 'myExtension',
preRegistration({ servicesManager }) {
servicesManager.registerService(WrappedBackEndService(servicesManager));
},
};
and the logic for your service shall be
// Canonical name of upper camel case BackEndService for the class
import BackEndService from './BackEndService';
export default function WrappedBackEndService(serviceManager) {
return {
// Note the canonical name of lower camel case backEndService
name: 'backEndService',
create: ({ configuration = {} }) => {
return new BackEndService(serviceManager);
},
};
}
with implementation of
export default class BackEndService {
constructor(serviceManager) {
this.serviceManager = serviceManager;
}
putAnnotations() {
return post(/*...*/);
}
}
with a registration of
import BackEndService from "../services/BackEndService/BackEndService";
export { BackEndService };