GithubHelp home page GithubHelp logo

cyberflamego / inject Goto Github PK

View Code? Open in Web Editor NEW

This project forked from technove/inject

0.0 2.0 0.0 491 KB

A dependency injection library for TypeScript.

License: MIT License

TypeScript 99.21% JavaScript 0.79%

inject's Introduction

@technove/inject

Badge

A dependency injection library for TypeScript. With full support for custom injectors using promises.

Installation

yarn add @technove/inject reflect-metadata

Or on npm:

npm install --save @technove/inject reflect-metadata

Then at the top of your application's entry point, add the following line:

import "reflect-metadata";

And finally in your tsconfig.json, set experimentalDecorators and emitDecoratorMetadata to true.

Usage

Defining a service

import { get, Service } from "@technove/inject";

class MyLogger {
    log(message: string) {
        console.log(message);
    }
}

const logger = get(MyLogger); // when you need to get the service
logger.log("Hello, World!"); // -> "Hello, World!"

// the instance will always be the same for repeated calls
const logger2 = get(MyLogger);
logger === logger2; // true!

Using Abstract Classes

A popular use-case for dependency injection is to define a different implementation for each environment. This is possible by declaring an abstract class, then extending it for each environment.

import { get, register, Service } from "@technove/inject";

// logger.ts

abstract class Logger {
    abstract log(message: string): void;
}

// application.ts

class ProductionLogger extends Logger {
    log(message: string) {
        console.log("PROD:", message);
    }
}

register(ProductionLogger);

// test.ts

class TestingLogger extends Logger {
    log(message: string) {
        console.log("TEST:", message);
    }
}
register(TestingLogger);

// whenever you need a logger
const logger = get(Logger);
logger.log("Hello, World!");

Using Services in Other Services

Often you'll create a service that depends on another service. This is very easy to use, and is very flexible.

import { get, Service } from "@technove/inject";

class Logger {
    log(message: string) {
        console.log(message);
    }
}

class MyService {
    @Inject()
    private readonly logger!: Logger; // when you call get(MyService) the first time, this value will be filled

    logMessage() {
        this.logger.log("Hello, World!");
    }
}

get(MyService).logMessage(); // -> "Hello, World!"

Creating Custom Injection Providers

Sometimes you may want to create a custom provider. This is made very simple!

import { get, FieldProvider, Inject } from "@technove/inject";

const provider: FieldProvider = () => "Hello, World!";

class MyService {
    @Inject(provider)
    private readonly message!: string;

    logMessage() {
        console.log(this.message);
    }
}

get(MyService).logMessage(); // -> Hello, World!

These providers have access to the container, so they can even access other services! In fact, when you don't give a provider this is nearly equivalent what the default @Inject() uses:

const provider: FieldProvider = (container: Container) => container.get(Logger);

If you take arguments, you can make this fairly powerful. Say you had a filesystem service, you could use it to read files and inject it into your service:

const ReadFile = (path: string) => (container: Container) =>
    container.get(FileSystem).readFile(path);

class MyService {
    @Inject(ReadFile("myfile.json"))
    private readonly data!: string;
}

Creating Custom Injectors with Promises

This idea is taken even further once you add promises to it. FieldProviders can be marked async and return promised values.

const ReadJson = (path: string) => async () => {
    const contents = await readFile(path, "utf-8");
    return JSON.parse(contents);
};

class MyService {
    @Inject(ReadFile("myfile.json"))
    private readonly data!: any;
}

// NOTE:
// using `get(MyService)` will throw an error, because you cannot load services with async values using it.
// instead use the following:

await load(MyService).data; // has data from myfile.json!

License

MIT

inject's People

Contributors

paulbgd avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.