Create Re-usable Services in SharePoint Framework (SPFx)

SPFx (at least when I started back in November/December 2017) is very component oriented — you can do web parts or extensions. The components can be re-used easily enough but they almost always have a UI aspect to them. I had a lot of service type functions that have no UI and didn’t fit well into the web part / extension tooling SPFx provides.


I solved it by creating services as singletons. The following example portrays a “workflow service.” This service knows how to iterate over available SharePoint worfklows, start them, etc. Here’s singleton part of it:

import SPHttpClient from '@microsoft/sp-http/lib/spHttpClient/SPHttpClient';
import WebPartContext from '@microsoft/sp-webpart-base/lib/core/WebPartContext';
import {ConfigService} from '../../framework/services/ConfigService/ConfigService';

export class WorkflowService
{
    private static instance: EGWorkflowService;
    
    private constructor(private context: WebPartContext)
    {
        this.initialize();
    }
    
    public static getInstance()
    {
        if(!WorkflowService.instance)
        {
            throw "WorkflowService.ts: This service must first be 
            initialized using initializeInstance(context).";
        }
        return WorkflowService.instance;
    }
    
    public static initializeInstance(context: WebPartContext)
    { 
        if(!WorkflowService.instance)
        {
          EGWorkflowService.instance = new EGWorkflowService(context);
    }
    return WorkflowService.instance;
}
// Workflow service methods go here.

This follows the Singleton pattern. Here’s where you can look at that in more detail: https://stackoverflow.com/questions/30174078/how-to-define-singleton-in-typescript

I have to import SPHttpContext because I almost always use it in my services. And since these are individual “plain” TS files, they don’t benefit from the auto-wiring you get from an SPFx web part.


Here’s how I initialize a service from a web part:

public onInit(): Promise<void>
{
    return new Promise