@lakshamana.dev/registry
v1.0.0
Published
[![Build Status](https://app.travis-ci.com/Lakshamana/registry.svg?token=5TkPokWmq84tfapeZkyx&branch=main)](https://app.travis-ci.com/Lakshamana/registry)
Downloads
2
Readme
Registry
Are you tired of creating a thousand factory files?
Are you a lazy programmer (won't judge you tbh) and just want to do your thing and let the computer do the rest?
Are you tired of having to manually register your dependencies?
Description
Registry is a simple library that enable you to register and resolve dependencies automatically either via class or token.
Installation
$ npm install --save @lakshamana/registry
Usage
// Animal.ts
import { Injectable, InjectVariable } from '@/core/decorators'
@Injectable() // make sure to add this decorator to the classes you want to make injectable
export class Animal {
@InjectVariable() animalName: string // make sure you have set `ANIMAL_NAME` in your env variables
@InjectVariable('SPECIES_NAME') species: string // you can use a custom env variable name, instead
get tag (): string {
return `${this.animalName}: [species=${this.species}]`
}
eat (): void {
console.log(`${this.tag} is eating`)
}
}
// Bone.ts
export interface Canidae {
walk: () => void
eat: () => void
getAnimal: () => Animal
}
@Injectable()
export class Bone {
@Inject('dog') dog: Canidae // inject instance via token, useful to work with interfaces
printOwner (): void {
console.log(`[owner]: ${this.dog.getAnimal().tag}`)
}
}
// main.ts
const registry = Container.getRegistry() // get a registry singleton
registry.register([
Animal, // pass your classes to the registry
Bone,
{ // pass your instances using a token and a provider factory
provide: 'dog',
useFactory: () => new Dog(new Animal())
},
{ // you can pass your instances as a class as well
provide: 'cat',
useClass: Cat
}
])
// You can also get manually the instances from the registry
const animal = registry.get(Animal)
animal.eat() // <animalName>: [species=<species>] is eating
Notice that, if you're running TypeScript 5.x you may want to declare class properties from inside receiver constructor, like this:
class Class {
constructor(
@Inject() private readonly instance: AnotherInstance // if you annotated `AnotherInstance` with `@Injectable()`
) {}
method () {
// this.instance should be available here
}
}
API
Brief API and type definitions description
Container
This will (wait for it...) contain the registry as a singleton object to be used through your application
static getRegistry (): Registry
- Gets/creates and returns a registry singleton
Registry
register (dependencies: Array<Constructor | Provider>): Registry
- Registers the providers into the registry
get<T extends Constructor>(target: T | string): InstanceType<T>
- Retrieves a dependency from the registry by class or token string
Decorators
This will help you to make your classes injectable, inject your variables or instances
@Injectable()
: class decorator- Use it to annotate the classes you need to be injectable
@Inject(token: string)
: property decorator- Use it to annotate class properties you need instances to be injected to
@InjectVariable(key?: string)
: property decorator- Use it to annotate class properties you need variables to be injected to
Running examples from source code
Clone this repository, then run:
$ npm install
$ cp .env.example .env
$ npm run dev
Testing
$ npm test
$ npm run test:watch
$ npm run test:ci # check coverage
$ npm run test:staged
Contributing
Feel free to open issue and open PRs with due tests, and I'll check as soon as I can.
Notice that this project is using Semantic Versioning and Conventional Commits for versioning and commit message pattern respectively, so make sure to follow it. PRs that don't follow these patterns or don't have tests may be rejected.