Skip to main content

Dependency injection

In MonsterJS dependency injection is a design pattern in which a class or function receives another class or function that it depends on.

The providers function

import { providers } from '@monster-js/core';

The providers function is used to setup the classes and functions so that we can inject it to our component.

Syntax

providers(<component>, ...<dependencies>)

Example.

import { component, providers } from '@monster-js/core';
import { Service1 } from './service1.service';
import { Service2 } from './service2.service';

export function app() {
return <h1>App</h1>
}

component(app, 'app-root');
providers(app, Service1, Service2);

The providers array in module

The providers array in a module is another way to setup the classes and functions so that they can be injection to the components registered in the this module.

Example.

import { Module } from '@monster-js/core/module';
import { Service1 } from './service1.service';
import { Service2 } from './service2.service';

export const AppModule: Module = {
providers: [Service1, Service2]
};

Dependency configuration

We can also configure the dependency when we register it in providers array or in providers function. Instead of passing the class we can pass an object.

Example.

export const AppModule: Module = {
providers: [{ provider: Service1 }]
};

The useValue property

The useValue property is used to return a value instead of the class instance when resolving the dependencies.

Example.

import { Module } from '@monster-js/core/module';
import { Service1 } from './service1.service';

export const AppModule: Module = {
providers: [{ provider: Service1, useValue: { greeting: 'Hello world!' } }]
};

or

import { component, providers } from '@monster-js/core';
import { Service1 } from './service1.service';

export function app() {
return <h1>App</h1>
}

component(app, 'app-root');
providers(app, { provider: Service1, useValue: { greeting: 'Hello world!' } });

In the examples above, when we inject the Service1 into our component it will return the object { greeting: 'Hello world!' }.

The useClass property

The useClass property is used to replace the dependency with other class when resolving the dependencies.

Example.

import { Module } from '@monster-js/core/module';
import { Service1 } from './service1.service';
import { Service2 } from './service2.service';

export const AppModule: Module = {
providers: [{ provider: Service1, useClass: Service2 }]
};

or

import { component, providers } from '@monster-js/core';
import { Service1 } from './service1.service';
import { Service2 } from './service2.service';

export function app() {
return <h1>App</h1>
}

component(app, 'app-root');
providers(app, { provider: Service1, useClass: Service2 });

In the example above, when we inject the Service1 into our component it will return the resolved instance of Service2 instead.

Inject dependencies

When injecting the dependencies, we use the inject(<context>, <dependency>) function for component and directives. In services and guards we can inject the dependencies in the constructor(constructor(private <property_name>: <dependency>)).

Inject dependencies in component

import { component, providers, inject } from '@monster-js/core';
import { Service1 } from './service1.service';

export function app() {

const service1 = inject(this, Service1);

return <h1>App</h1>
}

component(app, 'app-root');
providers(app, Service1);

Inject dependencies in service

import { Service } from '@monster-js/core';
import { Service1 } from './service1.service';

@Service()
export class GreetingService {

constructor(private service1: Service1) {}

}

Inject dependencies in directive

import { directive, AllDirectivesArg } from '@monster-js/core';
import { Service1 } from './service1.service';

export function highlight(arg: AllDirectiveArg) {

const service1 = inject(arg.component, Service1);

}

directive(highlight, 'highlight');