Giter Site home page Giter Site logo

inversime's Introduction

Inversime

npm version downloads download size

About

Inversime is simple inject dependencies library.

Installation

You can install inversime using npm:

$ npm install inversime

Usage

type Container = {
  service: IBookService
  bookApiClient: BookApiClient
  useCase: GetBooksUseCase
};

type Book = {
  name: string
  read: boolean
}

class BookApiClient {
  async get (): Promise<Book[]> {
    return [
      { name: 'The name of the wind', read: true },
      { name: "The Wise Man's Fear", read: false },
      { name: 'The way of kings', read: true },
      { name: 'Word of radiance', read: false }
    ]
  }
}

class BookService {
  constructor (private deps: Pick<Container, 'bookApiClient'>) {}

  async get () {
    const books = await this.deps.bookApiClient.get()
    return books
  }
}

class GetBooksUseCase {
  constructor (private deps: Pick<Container, 'service'>) {}
  execute () {
    return this.deps.service.get()
  }
}

const container = inversime<Container>({
  service: Inversime.fromClass(BookService),
  bookApiClient: Inversime.fromClass(BookApiClient),
  useCase: Inversime.fromClass(GetBooksUseCase)
})

const books = await container.get('useCase').execute()
console.log(books.length) // 4

Singleton

You can add a book store in the previous code and you need keep a singleton instance.

type Container = {
  // Add store in the container type
  store: BookStore;
  service: IBookService
  bookApiClient: BookApiClient
  useCase: GetBooksUseCase
};

// Create the store
class BookStore {
  books: Book[]
  set (books: Book[]) {
    this.books = books
  }

  get () {
    return this.books
  }
}

class BookService {
  constructor (private deps: Pick<Container, 'bookApiClient'>) {}

  async get () {
    const books = await this.deps.bookApiClient.get()
    // Save books in the store
    this.deps.books.store.set(books)
    return books
  }
}

const container = inversime<Container>({
  service: Inversime.fromClass(BookService),
  bookApiClient: Inversime.fromClass(BookApiClient),
  useCase: Inversime.fromClass(GetBooksUseCase)
})

await container.get('useCase').execute()
const store = container.get('books').store

console.log(store.books.length) // 4

Context

Yo can group dependencies by differents contexts. For example we can create a book context.

type Container = {
  // Create group in the container type
  books: {
    apiClient: BookApiClient
    service: BookService
  },
  useCase: GetBooksUseCase
}

class BookService {
  // Use the books context
  constructor (private deps: Pick<Container, 'books'>) {}
  async get () {
    const books = await this.deps.books.apiClient.get()
    return books
  }
}

class GetBooksUseCase {
  // Use the books context
  constructor (private deps: Pick<Container, 'books'>) {}
  execute () {
    return this.deps.books.service.get()
  }
}

const container = inversime<Container>({
  // Create the context 
  books: Inversime.context({
    service: Inversime.fromClass(BookService),
    apiClient: Inversime.fromClass(BookApiClient),
  }),
  useCase: Inversime.fromClass(GetBooksUseCase)
})

const books = await container.get('useCase').execute()
console.log(store.books.length) // 4

Extract dependencies

You can have a class with dependencies as arguments and you don't have to modify the class.

type Container = {
  books: {
    store: BookStore;
  },
  apiClient: BookApiClient
  service: BookService
  useCase: GetBooksUseCase
}

class BookService implements IBookService {
  // Split dependencies in two arguments
  constructor (private apiClient: BookApiClient, private store: BookStore) {}

  async get () {
    const books = await this.apiClient.get()
    this.store.set(books)
    return books
  }
}

const container = inversime<Container>({
  books: Inversime.context({
    store: Inversime.singleton(() => new BookStore())
  }),
  apiClient: Inversime.fromClass(BookApiClient),
  // Extract dependencies with `Inversime.extract`
  service: Inversime.extract(Inversime.fromClass(BookService), ['apiClient', 'books.store']),
  useCase: Inversime.fromClass(GetBooksUseCase)
})

const books = await container.get('useCase').execute()
console.log(books.length) // 4

inversime's People

Contributors

evuz avatar

Watchers

 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.