0.4.0 • Published 7 months ago

di-tory v0.4.0

Weekly downloads
-
License
MIT
Repository
github
Last release
7 months ago

di-tory Coverage Status npm version npm downloads GitHub license

di-tory is a lightweight dependency injection library for TypeScript.

Installation

npm install di-tory

Documentation

See the GitHub Wiki for full documentation.

Example Usage

Below is a simple usage example.

Getting Started

All example files examples/getting-started.

import { Module } from 'di-tory';
import { Logger } from './Logger';
import { UserRepository } from './UserRepository';
import { AuthService } from './AuthService';
import { signIn } from './signInUseCase';

const App = Module()
  .private({
    logger: (_, { logLevel }: { logLevel: string }) => new Logger(logLevel),
  })
  .private({
    userRepository: () => new UserRepository(),
  })
  .private({
    authService: ({ userRepository }) => new AuthService(userRepository),
  })
  .publicImpl({
    signIn,
  });

async function main() {
  const app = App.create({ logLevel: 'debug' });
  const user = await app.signIn('user', 'password');

  console.log(user);
}

main().catch(console.error);

Using With Express

All example files examples/express.

src/index.ts - Composition Root

import { Module, Scope } from 'di-tory';
import asyncDiScope from 'di-tory/async-scope';
import asyncScopeNodeApi from 'di-tory/async-scope/node';
import RequestId from './RequestId';
import Logger from './Logger';
import UserRepository from './UserRepository';
import AuthService from './AuthService';
import createExpressApp from './ExpressApp';

asyncDiScope.init(asyncScopeNodeApi);

const App = Module()
  .private(
    {
      asyncRequestId: () => new RequestId(),
    },
    Scope.async,
  )
  .privateImpl({
    setRequestId({ asyncRequestId }, requestId?: string) {
      asyncRequestId.requestId = requestId;
    },
    getRequestId({ asyncRequestId }) {
      return asyncRequestId.requestId;
    },
  })
  .private({
    logger: ({ getRequestId }, { level }: { level: string }) =>
      new Logger(level, getRequestId),
  })
  .private({
    userRepo: ({ logger }) => new UserRepository(logger),
  })
  .private({
    auth: ({ userRepo, logger }) => new AuthService(userRepo, logger),
  })
  .private({
    app: ({ setRequestId, auth, logger }, { port }: { port: number }) =>
      createExpressApp(setRequestId, auth, logger, port),
  })
  .public({
    run: ({ app }) => app.run,
  });

const app = App.create({ port: 3000, level: 'debug' });
app.run();

src/ExpressApp.ts - Express App

import express from 'express';
import asyncDiScope from 'di-tory/async-scope';
import type { IAuthService, IInfoLogger } from './interfaces';

export default function createExpressApp(
  setRequestId: (requestId: string | undefined) => void,
  auth: IAuthService,
  logger: IInfoLogger,
  port: number,
) {
  const app = express();

  app.use((req, res, next) => {
    asyncDiScope.run(() => next());
  });

  app.use((req, res, next) => {
    setRequestId(req.header('X-Request-Id'));
    next();
  });

  // -- snip --

  app.use(express.json());

  app.post('/login', async (req, res, next) => {
    const { userName, password } = req.body;

    // -- snip --

    try {
      const result = await auth.authenticate(userName, password);
      res.status(200).json(result);
    } catch (error) {
      next(error);
    }
  });

  // -- snip --

  return {
    run() {
      app.listen(port, () => {
        logger.info(`Server running on port ${port}`);
      });
    },
  };
}
0.3.0

7 months ago

0.2.3

7 months ago

0.4.0

7 months ago

0.3.1

7 months ago

0.2.5

7 months ago

0.2.4

7 months ago

0.2.2

7 months ago

0.2.1

7 months ago

0.2.0

7 months ago

0.1.1

7 months ago

0.1.0

7 months ago