Service Container

Symfony uses a dependency injection container, and our frontend as well can use a service container.

The main difference is that the dependencies are injected in Symfony, while in JS we actively fetch them from the container. While dependency injection is way more clean, the service locator leads to simpler and smaller frontend code. Thatā€™s why we keep using this pattern there.

The idea is that you basically have a singleton container, that you can fetch everywhere.

Create a container.ts in your code with this code:

import Liim from "liim";

const container = new Liim();
export default container;

In your main JS entry, you can then add all your relevant services before mounting any component:

import container from "./rieber/container";

container.set("data", data);
container.set("fetch", fetch);
container.set("loader", loader);
container.set("toasts", toasts);
container.set("translator", translator);
// ..

And now your components can use this service locator, without needing to pass everything as parameter:

export function someTsxComponents (props): JSX.Element
{
    const translator = container.get<Translator>("translator");

    return <p>{translator.trans("some-message")}</p>;
}

Your components may never use these dependencies statically, so no global

import container from "./rieber/container";

const translator = container.get<Translator>("translator");

But only ever use it in your constructor / function body. Because the ES module imports are resolved all at once and therefore the service will not exist (as the imports are resolved before any script is run, including your ā€œfill the containerā€ code).

Mayd

The Mayd backend has container as well, it is accessible via

import app from "@mayd/app";

It has the same interface as Liim.

Table of Contents