npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@yobuligo/service-provider.typescript

v1.0.3

Published

A dependency injection implementation for TypeScript by using a service provider / service locator.

Downloads

2

Readme

service-provider.typescript

A dependency injection implementation in TypeScript by using a service provider / service locator.

Installation

Install the service provider via:

npm install --save @yobuligo/service-provider.typescript

Usage

The service provider is used to achieve independency from concrete classes and to write more flexible code. Instead of initializing concrete service classes, a service is requested from the service provider via a service definition. The service definition is connected to a service type, which is normally represented by an interface type.

At a central point the concrete services, which should be used in a session, have to be provided to the service provider either by setting initialized services or by providing the concrete service type class. When requesting a service the service provider initializes the services lazy on demand.

After providing the services, these services can be fetched by the service provider. At that point there is no dependency anymore to concrete service implementations but instead to the abstract service type.

The following chapter shows how to provide and consume a service.

Implement a service

At first a service has to be implemented and it has to be connected with a service definition. Implementing a service requires the following steps:

  1. Implement the service type
interface ILogger {
  log(message: string): void;
}
  1. Implement the service definition class which references the service type. This class must extend ServiceDefinition. It is the key which is used to provide or consume a service.

A service definition per service is required, as an interface type as service type only exists at designtime, but there must be a concrete type (the service definition class) which is available at runtime, which can be analyzed and which is connected to the service type.

class LoggerService extends ServiceDefinition<ILogger> {}
  1. Implement a variant of the the service itself.
class Logger implements ILogger {
  log(message: string): void {
    console.log(message);
  }
}

Provide a service to the service provider

To request a service from the service provider, it has to be provided first, generally at a central place within an application. Currently some kind of autowiring is not supported. There are two ways to provide a service which are explained below.

Hint: Providing an already existing service type would replace the current service.

  1. Put a service

Put is used to add an already initialized service to the service provider. Therefore the service definition, which is connected to the abstract service type, has to be injected as first parameter. As second parameter the service instance, which must be of type of the abstract service type, has to be passed.

To put a service means it is handled as a singleton service. Each time that service is requested, the same instance will be returned.

const logger: ILogger = new Logger();
SP.put(LoggerService, logger);
  1. Register a service

Registering means to only provide the concrete service class, without the need to initialize the service before. Instead the service provider will initialize the service lazily on demand. Currently only services without constructor parameters are supported.

There are two mandatory parameters for the registration. The service definition, which is connected to the abstract service type, and the concrete service class type.

Optionally the parameter serviceInstanceType can be set. It defines if a new service instance is created with each request or if the service is handled as singleton, which means once the service is initialized the same instance is returned with each request. As default the serviceInstanceType is considered to be SINGLE_INSTANTIABLE.

SP.register(LoggerService, Logger);

SP.register(LoggerService, Logger, ServiceInstanceType.MULTI_INSTANTIABLE);

Request a service

Requesting a service is possible by providing the corresponding service definition, which is connected to the abstract service type, to the methods fetch or fetchOrNull. As the service definition is connected to the abstract service type, the caller has only a dependency to that service type. The concrete service class type is unknown. Below two examples are shown for fetching services:

  1. Fetch

By using fetch the caller expects the service to be available. The service provider returns an instance of the service type or throws an exception if the service doesn't exist.

const logger = SP.fetch(LoggerService);
logger.log(`Message to be logged`);
  1. FetchOrNull

FetchOrNull is equivalent to fetch but in case that the requested service doesn't exist, undefined is returned instead of throwing an exception.

const logger = SP.fetchOrNull(LoggerService);
logger?.log(`Message to be logged`);

Remove a service

To remove a service from the service provider, pass the service definition, which is connected to the abstract service type, to remove.

SP.remove(LoggerService);

Check if a service exist

The methods contain and containsNot can be used to find out, if a service was defined in the service provider. It provides more readability and it avoids having to initialize the service by calling fetch.

const contains = SP.contains(LoggerService);

const containsNot = SP.containsNot(LoggerService);