ohif-viewer/docs/latest/managers/service.md
Alireza 5643f8f6d2
feat: Added documentation for OHIF-v3 (#2450)
* Added docs with new screenshots

* Added doc to architecture

* Added documentations to various extension modules

* Added more documentation to modes

* Added docs to managers

* Added docs for services

* Fixed deployment docs

* Added white labelling documentation

* Added i18n docs and measurement export
2021-06-15 11:15:29 -04:00

3.9 KiB

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 configuration
  • registerServices: 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.

// platform/viewer/src/appInit.js

servicesManager.registerServices([
    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:

// platform/core/src/services/ToolBarService/index.js

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

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.

// extensions/customExtension/src/index.js

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

// extensions/customExtension/src/services/backEndService/index.js
import backEndService from './backEndService';

export default function WrappedBackEndService(serviceManager) {
  return {
    name: 'myService',
    create: ({ configuration = {} }) => {
      return new backEndService(serviceManager);
    },
  };
}

with implementation of

export default class backEndService {
  constructor(serviceManager) {
    this.serviceManager = serviceManager;
  }

  putAnnotations() {
    return post(/*...*/);
  }
}