Overview
The @sodacore/di
package provides a simple and lightweight dependency injection container for TypeScript, it utilises the @sodacore/registry package to store and resolve dependencies and is built to be easy to use.
The DI package can be used entirely separately (of course alongside the registry) to manage dependencies in your own separate applications as well.
Usage
There are 2 decorators and a series of utility methods that are available; see below.
Decorator: @Provide
The @Provide
decorator is used to register a class as a provider, this means that the class can be injected into other classes that require it.
import { Provide } from '@sodacore/di';
@Provide()
export default class SomeProvider {
public myMethod() {
return 'Hello World';
}
}
Decorator: @Inject
The @Inject
decorator is used to inject a provider (or within a sodacore application, almost any part of the application) into a class, this means that the provider will be available as a property on the class.
import { Controller, Get } from '@sodacore/http';
import { Inject } from '@sodacore/di';
import SomeProvider from '../providers/some';
@Controller('/api/v1/something')
export default class SomethingController {
@Inject() private some!: SomeProvider;
@Get('/')
public async getSomething() {
return this.some.myMethod();
}
}
Note: you will need to ensure any classes that you want to inject is a standard import, NOT a
import type
which it can sometimes default to, this is because we expect the class instance to call upon the class's constructor information.
Utility: setMeta
The setMeta
utility method is a simple helper method that allows you to set metadata to a class with support for prefixing.
import { Utils } from '@sodacore/di';
class MyClass {}
Utils.setMeta('someKey')(MyClass, 'someValue');
// Sets: `@sodacore:someKey` = 'someValue'
Utils.setMeta('someKey', 'someNamespace')(MyClass, 'someValue');
// Sets: `@sodacore:someNamespace:someKey` = 'someValue'
Utils.setMeta('someKey', undefined, true)(MyClass, 'someValue');
// Sets: `someKey` = 'someValue'
Lastly, you can set metadata on a class method instead of the class, as the 3rd argument in the second function is an optional propertyKey.
import { Utils } from '@sodacore/di';
class MyClass {
public someMethod() {
return 'foo';
}
}
Utils.setMeta('someKey')(MyClass, 'someValue', 'someMethod');
Utility: getMeta
The getMeta
utility method is a simple helper method that allows you to get metadata from a class with support for prefixing and fallback alongside a generic for typing the return.
import { Utils } from '@sodacore/di';
class MyClass {
public someMethod() {
return 'foo';
}
}
// Class metadata.
Utils.setMeta('someKey')(MyClass, 'someValue');
const resultValue = Utils.getMeta<string>('someKey')(MyClass);
// Result: 'someValue'
// Class metadata with fallback.
const resultValue = Utils.getMeta<string>('someNonExistentKey')(MyClass, undefined, 'defaultValue');
// Result: 'defaultValue'
// Method metadata.
Utils.setMeta('someKey')(MyClass, 'someValue', 'someMethod');
const resultValue = Utils.getMeta('someKey')(MyClass, 'someMethod');
// Result: 'someValue'
Utility: getMetaPrefix
A simple function to use the internal prefixing that the above utility methods use.
import { Utils } from '@sodacore/di';
const result = Utils.getMetaPrefix('someKey', 'someNamespace');
// Result: '@sodacore:someNamespace:someKey'