ironbean
TypeScript icon, indicating that this package has built-in type declarations

1.0.21 • Public • Published

ironbean

Ironbean is dependency injection library for Typescript or Javascript. The reason of creation: I needed DIC for a typescript, but I wasn't satisfied with any other libraries. Most of them are outdated, and they lack type safety and test environment.

During development, I emphasized on:

  • understandable and easy to use API
  • option of test environment
  • type safety support for typescript
  • annotation support

Installation

Install by npm

npm install --save ironbean

Modify your tsconfig.json to include the following settings

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

Documentation

Class component

Components are definitions for ironbean which instantiate.

@component
class DbTodoStorage {
    private db: Db;
    constructor(db: Db) {
        this.db = db;
    }

    saveTodo(todo: Todo): void {
        //...
    }
}

Dependency token

Identifies dependencies which are not identifiable by class. For example interfaces.

import {DependencyToken} from "ironbean";

const ITodoStorage = DependencyToken.create<ITodoStorage>("TODO_STORAGE");

Use annotation @type for dependency identification.

import {component, type} from "ironbean";

@component
class TodoList {
    private storage: ITodoStorage;
    constructor(@type(ITodoStorage) storage: ITodoStorage) {
        this.storage = storage;
    }
}

There are two ways how ironbean can create instances for dependency tokens:

  • Bind token to class component.

    import {take} from "ironbean";
    
    // for ITodoStorage use DbTodoStorage
    take(ITodoStorage).bindTo(DbTodoStorage);

    ironbean creates an instance of class component.

  • Set factory for dependency token

    import {take, ComponentContext} from "ironbean";
    
    take(ITodoStorage).setFactory((context: ComponentContext): ITodoStorage => {
         // factory for create instance
         return createTodoStorage();
    });

ApplicationContext

ApplicationContext is used for getting dependencies from current scope.

Getting ApplicationContext

Behaviour of ApplicationContext is the same as behaviour of the component. We can get the instance of ApplicationContext by using any type of injection.

If we need to get instance of ApplicationContext in global environment, for example for starting an application, we use function getBaseApplicationContext().

import {getBaseApplicationContext} from "ironbean";

const context = getBaseApplicationContext();

const app = context.getBean(Application);
app.run();

Methods description

  • public getBean<T>(dependency: Dependency<T>): T
    • is used for getting dependencies
    • we need dependency token

ComponentContext

ComponentContext is used for getting dependencies intro component. Behaviour is almost the same as ApplicationContext, the difference is that component with type prototype memorizes instances that were created in previous request of the same dependency token. All types of injection inside the components used in background ComponentContext.

Inject types in class components

Constructor injection

Intuitive instance getting by constructor, if you use typescript with reflection you only need to specify type of class, if not, use decorator @type.

import {component} from "ironbean";

@component
class Enginge {
   
}

@component
class Car {
   private readonly enginge: Enginge;

   constructor(enginge: Enginge) {
       this.enginge = enginge;
   }
}

Property injection

To inject the instance to property use decorator @autowired, if you use reflection, use @type.

import {component, autowired} from "ironbean";

@component
class Enginge {

}

@component
class Car {
   @autowired
   private readonly enginge: Enginge;
}

Method injection

You can achieve method injection by using decorator @postConstruct, it's similar principle as the Constructor injection, with the only difference that method marked as @postConstruct is called after initialization of the component instance

import {component, postConstruct} from "ironbean";

@component
class Engine {

}

@component
class Car {
   private engine: Engine;
   
   @postConstruct
   injectWheel(engine: Engine) {
       this.engine = engine;
   }
}

Context injection - not recommended

You can get the instance from context itself using method getBean(). I don't recommend using this method, because its anti-pattern. It doesn't make sense obtaining whole piano just to get an instance of a key when you can ask for the key directly. This option exists here as a last resort in case of some difficulties, for example if I would need to create more instances of prototype dependencies within one component.

import {component, ApplicationContext} from "ironbean";

@component
class Engine {

}

@component
class Car {
   private engine: Engine;
   
   constructor(context: ApplicationContext) {
       this.engine = context.getBean(Engine);
   }
}

Package Sidebar

Install

npm i ironbean

Weekly Downloads

89

Version

1.0.21

License

MIT

Unpacked Size

215 kB

Total Files

116

Last publish

Collaborators

  • killov